]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
karo: merge with Ka-Ro specific tree for secure boot support
authorLothar Waßmann <LW@KARO-electronics.de>
Wed, 4 Mar 2015 12:41:53 +0000 (13:41 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 4 Mar 2015 12:41:53 +0000 (13:41 +0100)
210 files changed:
1  2 
.gitignore
Kconfig
README
arch/arm/Kconfig
arch/arm/config.mk
arch/arm/cpu/arm926ejs/mxs/mxs.c
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/arm926ejs/mxs/timer.c
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/lowlevel_init.S
arch/arm/cpu/armv7/mx5/clock.c
arch/arm/cpu/armv7/mx5/lowlevel_init.S
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap-common/boot-common.c
arch/arm/imx-common/iomux-v3.c
arch/arm/imx-common/timer.c
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/gpio.h
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-exynos/system.h
arch/arm/include/asm/arch-mx5/clock.h
arch/arm/include/asm/arch-mx5/crm_regs.h
arch/arm/include/asm/arch-mx5/imx-regs.h
arch/arm/include/asm/arch-mx5/sys_proto.h
arch/arm/include/asm/arch-mx6/clock.h
arch/arm/include/asm/arch-mx6/crm_regs.h
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/emif.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/imx-common/dma.h
arch/arm/include/asm/imx-common/iomux-v3.h
arch/arm/include/asm/system.h
arch/arm/lib/asm-offsets.c
arch/arm/lib/board.c
arch/arm/lib/cache-cp15.c
arch/arm/lib/cache.c
arch/arm/lib/crt0.S
arch/arm/lib/interrupts.c
arch/arm/lib/reset.c
arch/arm/lib/vectors.S
board/boundary/nitrogen6x/nitrogen6x.c
board/congatec/cgtqmx6eval/cgtqmx6eval.c
board/denx/m28evk/spl_boot.c
board/freescale/mx6qarm2/mx6qarm2.c
board/freescale/mx6qsabreauto/mx6qsabreauto.c
board/freescale/mx6qsabrelite/mx6qsabrelite.c
board/freescale/mx6sabresd/mx6sabresd.c
board/karo/common/Makefile
board/karo/common/karo.h
board/karo/common/mmc.c
board/karo/common/nand.c
board/karo/tx28/Kconfig
board/karo/tx28/Makefile
board/karo/tx28/flash.c
board/karo/tx28/tx28.c
board/karo/tx48/Kconfig
board/karo/tx48/Makefile
board/karo/tx48/spl.c
board/karo/tx48/tx48.c
board/karo/tx51/Kconfig
board/karo/tx51/Makefile
board/karo/tx51/tx51.c
board/karo/tx53/Kconfig
board/karo/tx53/Makefile
board/karo/tx53/flash.c
board/karo/tx53/tx53.c
board/karo/tx6/Kconfig
board/karo/tx6/Makefile
board/karo/tx6/config.mk
board/karo/tx6/flash.c
board/karo/tx6/ltc3676.c
board/karo/tx6/pmic.c
board/karo/tx6/pmic.h
board/karo/tx6/rn5t567.c
board/karo/tx6/rn5t618.c
board/karo/tx6/tx6qdl.c
board/karo/tx6/u-boot.lds
board/wandboard/wandboard.c
common/Kconfig
common/Makefile
common/cmd_bootce.c
common/cmd_gpt.c
common/cmd_mmc.c
common/cmd_mtdparts.c
common/cmd_nand.c
common/env_nand.c
common/fdt_support.c
common/lcd.c
common/spl/spl.c
common/spl/spl_nand.c
common/xyzModem.c
configs/tx28-40x1_defconfig
configs/tx28-40x1_noenv_defconfig
configs/tx28-40x2_defconfig
configs/tx28-40x2_noenv_defconfig
configs/tx28-40x3_defconfig
configs/tx28-40x3_noenv_defconfig
configs/tx28-41x0_defconfig
configs/tx28-41x0_noenv_defconfig
configs/tx48_defconfig
configs/tx51-8xx0_defconfig
configs/tx51-8xx1_2_defconfig
configs/tx53-1232_defconfig
configs/tx53-x030_defconfig
configs/tx53-x130_defconfig
configs/tx53-x131_defconfig
configs/tx6q-1020_defconfig
configs/tx6q-1020_mfg_defconfig
configs/tx6q-1020_noenv_defconfig
configs/tx6q-10x0_defconfig
configs/tx6q-10x0_mfg_defconfig
configs/tx6q-10x0_noenv_defconfig
configs/tx6q-11x0_defconfig
configs/tx6q-11x0_mfg_defconfig
configs/tx6q-11x0_noenv_defconfig
configs/tx6s-8034_defconfig
configs/tx6s-8034_mfg_defconfig
configs/tx6s-8034_noenv_defconfig
configs/tx6s-8035_defconfig
configs/tx6s-8035_mfg_defconfig
configs/tx6s-8035_noenv_defconfig
configs/tx6u-8011_defconfig
configs/tx6u-8011_mfg_defconfig
configs/tx6u-8011_noenv_defconfig
configs/tx6u-8012_defconfig
configs/tx6u-8012_mfg_defconfig
configs/tx6u-8012_noenv_defconfig
configs/tx6u-8033_defconfig
configs/tx6u-8033_mfg_defconfig
configs/tx6u-8033_noenv_defconfig
configs/tx6u-80x0_defconfig
configs/tx6u-80x0_mfg_defconfig
configs/tx6u-80x0_noenv_defconfig
configs/tx6u-8111_defconfig
configs/tx6u-8111_mfg_defconfig
configs/tx6u-8111_noenv_defconfig
configs/tx6u-81x0_defconfig
configs/tx6u-81x0_mfg_defconfig
configs/tx6u-81x0_noenv_defconfig
disk/part.c
drivers/dma/Kconfig
drivers/dma/apbh_dma.c
drivers/gpio/Makefile
drivers/gpio/am33xx_gpio.c
drivers/gpio/gpio-uclass.c
drivers/gpio/gpiolib.c
drivers/gpio/mxc_gpio.c
drivers/i2c/Kconfig
drivers/misc/fsl_iim.c
drivers/mmc/Kconfig
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mtd/Kconfig
drivers/mtd/nand/Kconfig
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_spl_simple.c
drivers/mtd/nand/omap_gpmc.c
drivers/net/Kconfig
drivers/net/cpsw.c
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h
drivers/net/phy/Kconfig
drivers/net/phy/phy.c
drivers/net/phy/smsc.c
drivers/serial/serial_mxc.c
drivers/usb/host/ehci-mx6.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
drivers/video/mxc_ipuv3_fb.c
drivers/video/mxsfb.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/imx_watchdog.c
dts/Kconfig
include/ahci.h
include/asm-generic/gpio.h
include/configs/tx25.h
include/configs/tx28.h
include/configs/tx48.h
include/configs/tx51.h
include/configs/tx53.h
include/configs/tx6.h
include/fsl_esdhc.h
include/ipu.h
include/lcd.h
include/nand.h
include/net.h
include/netdev.h
include/spl.h
net/Makefile
net/bootp.c
net/bootp.h
net/net.c
tools/Makefile

diff --combined .gitignore
index a40c277105ea65efe81a70c53715099adf6d2548,7b59233ebd293f29901d776b8b826276cd5bc32c..2cba50167ed64d20ba0da20a802dd46a41f33a60
@@@ -5,24 -5,18 +5,24 @@@
  #
  # Normal rules
  #
 -
 -*.rej
 -*.orig
 -*.a
 +.*
  *.o
 +*.o.*
 +*.a
 +*.s
  *.su
 -*~
 +*.mod.c
 +*.i
 +*.lst
 +*.order
 +*.elf
  *.swp
 -*.patch
  *.bin
 +*.patch
  *.cfgtmp
 -*.dts.tmp
 +
 +# host programs on Cygwin
 +*.exe
  
  # Build tree
  /build-*
  #
  # Top-level generic files
  #
 -
 -/MLO
 +/MLO*
  /SPL
  /System.map
 -/u-boot
 -/u-boot.hex
 -/u-boot.imx
 -/u-boot-with-spl.imx
 -/u-boot-with-nand-spl.imx
 -/u-boot.map
 -/u-boot.srec
 -/u-boot.ldr
 -/u-boot.ldr.hex
 -/u-boot.ldr.srec
 -/u-boot.img
 -/u-boot.kwb
 -/u-boot.sha1
 -/u-boot.dis
 -/u-boot.lds
 -/u-boot.ubl
 -/u-boot.ais
 -/u-boot.dtb
 -/u-boot.sb
 -/u-boot.bd
 -/u-boot.geany
 +/u-boot*
 +/boards.cfg
  
  #
 -# Generated files
 +# git files that we don't want to ignore even it they are dot-files
  #
 +!.gitignore
 +!.mailmap
  
 -*.depend*
 +#
 +# Generated files
 +#
  /LOG
 -/errlog
 -/reloc_off
 +/spl/
 +/tpl/
  
 +#
 +# Generated include files
 +#
 +/include/config/
  /include/generated/
 -asm-offsets.s
  
  # stgit generated dirs
  patches-*
@@@ -62,6 -69,7 +62,7 @@@
  # quilt's files
  patches
  series
+ .pc
  
  # gdb files
  .gdb_history
@@@ -80,6 -88,5 +81,6 @@@ GRTAG
  GSYMS
  GTAGS
  
 -# spl ais files
 -/spl/*.ais
 +*.orig
 +*~
 +\#*#
diff --combined Kconfig
index 60cf1dd1c1f2140ce1cda90a554f427b1875d2d2,0000000000000000000000000000000000000000..3e74c891b0928540f2b1dfc69e7a64b9c1237c87
mode 100644,000000..100644
--- /dev/null
+++ b/Kconfig
@@@ -1,160 -1,0 +1,159 @@@
-       depends on $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
-       default y
 +#
 +# For a description of the syntax of this configuration file,
 +# see Documentation/kbuild/kconfig-language.txt.
 +#
 +mainmenu "U-Boot $UBOOTVERSION Configuration"
 +
 +config UBOOTVERSION
 +      string
 +      option env="UBOOTVERSION"
 +
 +config KCONFIG_OBJDIR
 +      string
 +      option env="KCONFIG_OBJDIR"
 +
 +menu "General setup"
 +
 +config LOCALVERSION
 +      string "Local version - append to U-Boot release"
 +      depends on !SPL_BUILD
 +      help
 +        Append an extra string to the end of your U-Boot version.
 +        This will show up on your boot log, for example.
 +        The string you set here will be appended after the contents of
 +        any files with a filename matching localversion* in your
 +        object and source tree, in that order.  Your total string can
 +        be a maximum of 64 characters.
 +
 +config LOCALVERSION_AUTO
 +      bool "Automatically append version information to the version string"
 +      depends on !SPL_BUILD
 +      default y
 +      help
 +        This will try to automatically determine if the current tree is a
 +        release tree by looking for git tags that belong to the current
 +        top of tree revision.
 +
 +        A string of the format -gxxxxxxxx will be added to the localversion
 +        if a git-based tree is found.  The string generated by this will be
 +        appended after any matching localversion* files, and after the value
 +        set in CONFIG_LOCALVERSION.
 +
 +        (The actual string used here is the first eight characters produced
 +        by running the command:
 +
 +          $ git rev-parse --verify HEAD
 +
 +        which is done within the script "scripts/setlocalversion".)
 +
 +config CC_OPTIMIZE_FOR_SIZE
 +      bool "Optimize for size"
 +      depends on !SPL_BUILD
 +      default y
 +      help
 +        Enabling this option will pass "-Os" instead of "-O2" to gcc
 +        resulting in a smaller U-Boot image.
 +
 +        This option is enabled by default for U-Boot.
 +
 +menuconfig EXPERT
 +        bool "Configure standard U-Boot features (expert users)"
 +        help
 +          This option allows certain base U-Boot options and settings
 +          to be disabled or tweaked. This is for specialized
 +          environments which can tolerate a "non-standard" U-Boot.
 +          Only use this if you really know what you are doing.
 +
 +endmenu               # General setup
 +
 +menu "Boot images"
 +
 +config SPL_BUILD
 +      bool
++      default y if $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
 +
 +config TPL_BUILD
 +      bool
 +      depends on $KCONFIG_OBJDIR="tpl"
 +      default y
 +
 +config SUPPORT_SPL
 +      bool
 +
 +config SUPPORT_TPL
 +      bool
 +
 +config SPL
 +      bool
 +      depends on SUPPORT_SPL
 +      prompt "Enable SPL" if !SPL_BUILD
 +      default y if SPL_BUILD
 +      help
 +        If you want to build SPL as well as the normal image, say Y.
 +
 +config TPL
 +      bool
 +      depends on SPL && SUPPORT_TPL
 +      prompt "Enable TPL" if !SPL_BUILD
 +      default y if TPL_BUILD
 +      default n
 +      help
 +        If you want to build TPL as well as the normal image and SPL, say Y.
 +
 +config FIT
 +      bool "Support Flattened Image Tree"
 +      depends on !SPL_BUILD
 +      help
 +        This option allows to boot the new uImage structrure,
 +        Flattened Image Tree.  FIT is formally a FDT, which can include
 +        images of various types (kernel, FDT blob, ramdisk, etc.)
 +        in a single blob.  To boot this new uImage structure,
 +        pass the the address of the blob to the "bootm" command.
 +
 +config FIT_VERBOSE
 +      bool "Display verbose messages on FIT boot"
 +      depends on FIT
 +
 +config FIT_SIGNATURE
 +      bool "Enabel signature verification of FIT uImages"
 +      depends on FIT
 +      help
 +        This option enables signature verification of FIT uImages,
 +        using a hash signed and verified using RSA.
 +        See doc/uImage.FIT/signature.txt for more details.
 +
 +config SYS_EXTRA_OPTIONS
 +      string "Extra Options (DEPRECATED)"
 +      depends on !SPL_BUILD
 +      help
 +        The old configuration infrastructure (= mkconfig + boards.cfg)
 +        provided the extra options field. If you have something like
 +        "HAS_BAR,BAZ=64", the optional options
 +          #define CONFIG_HAS
 +          #define CONFIG_BAZ  64
 +        will be defined in include/config.h.
 +        This option was prepared for the smooth migration from the old
 +        configuration to Kconfig. Since this option will be removed sometime,
 +        new boards should not use this option.
 +
 +config SYS_TEXT_BASE
 +      depends on SPARC
 +      hex "Text Base"
 +      help
 +        TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
 +
 +endmenu               # Boot images
 +
 +source "arch/Kconfig"
 +
 +source "common/Kconfig"
 +
 +source "dts/Kconfig"
 +
 +source "net/Kconfig"
 +
 +source "drivers/Kconfig"
 +
 +source "fs/Kconfig"
 +
 +source "lib/Kconfig"
diff --combined README
index 0fec497328bd5fd27df28efda7a14d828a106346,06c09c5c478e3b33ff7f3b30b1e6b2954787140a..4f8842d2926e9a75b2c513103041aeb07095f3a0
--- 1/README
--- 2/README
+++ b/README
@@@ -35,7 -35,7 +35,7 @@@ Makefile have been tested to some exten
  "working". In fact, many of them are used in production systems.
  
  In case of problems see the CHANGELOG and CREDITS files to find out
 -who contributed the specific port. The MAINTAINERS file lists board
 +who contributed the specific port. The boards.cfg file lists board
  maintainers.
  
  Note: There is no CHANGELOG file in the actual U-Boot source tree;
@@@ -132,10 -132,6 +132,10 @@@ Directory Hierarchy
  ====================
  
  /arch                 Architecture specific files
 +  /arc                        Files generic to ARC architecture
 +    /cpu              CPU specific files
 +      /arc700         Files specific to ARC 700 CPUs
 +    /lib              Architecture specific library files
    /arm                        Files generic to ARM architecture
      /cpu              CPU specific files
        /arm720t                Files specific to ARM 720 CPUs
        /at91           Files specific to Atmel AT91RM9200 CPU
        /imx            Files specific to Freescale MC9328 i.MX CPUs
        /s3c24x0        Files specific to Samsung S3C24X0 CPUs
 -      /arm925t                Files specific to ARM 925 CPUs
        /arm926ejs      Files specific to ARM 926 CPUs
        /arm1136                Files specific to ARM 1136 CPUs
 -      /ixp            Files specific to Intel XScale IXP CPUs
        /pxa            Files specific to Intel XScale PXA CPUs
 -      /s3c44b0                Files specific to Samsung S3C44B0 CPUs
        /sa1100         Files specific to Intel StrongARM SA1100 CPUs
      /lib              Architecture specific library files
    /avr32              Files generic to AVR32 architecture
    /blackfin           Files generic to Analog Devices Blackfin architecture
      /cpu              CPU specific files
      /lib              Architecture specific library files
 -  /x86                        Files generic to x86 architecture
 -    /cpu              CPU specific files
 -    /lib              Architecture specific library files
    /m68k                       Files generic to m68k architecture
      /cpu              CPU specific files
        /mcf52x2                Files specific to Freescale ColdFire MCF52x2 CPUs
    /mips                       Files generic to MIPS architecture
      /cpu              CPU specific files
        /mips32         Files specific to MIPS32 CPUs
 -      /xburst         Files specific to Ingenic XBurst CPUs
 +      /mips64         Files specific to MIPS64 CPUs
      /lib              Architecture specific library files
    /nds32              Files generic to NDS32 architecture
      /cpu              CPU specific files
    /nios2              Files generic to Altera NIOS2 architecture
      /cpu              CPU specific files
      /lib              Architecture specific library files
 +  /openrisc           Files generic to OpenRISC architecture
 +    /cpu              CPU specific files
 +    /lib              Architecture specific library files
    /powerpc            Files generic to PowerPC architecture
      /cpu              CPU specific files
        /74xx_7xx               Files specific to Freescale MPC74xx and 7xx CPUs
        /mpc5xx         Files specific to Freescale MPC5xx CPUs
        /mpc5xxx                Files specific to Freescale MPC5xxx CPUs
        /mpc8xx         Files specific to Freescale MPC8xx CPUs
 -      /mpc824x                Files specific to Freescale MPC824x CPUs
        /mpc8260                Files specific to Freescale MPC8260 CPUs
        /mpc85xx                Files specific to Freescale MPC85xx CPUs
        /ppc4xx         Files specific to AMCC PowerPC 4xx CPUs
        /leon2          Files specific to Gaisler LEON2 SPARC CPU
        /leon3          Files specific to Gaisler LEON3 SPARC CPU
      /lib              Architecture specific library files
 +  /x86                        Files generic to x86 architecture
 +    /cpu              CPU specific files
 +    /lib              Architecture specific library files
  /api                  Machine/arch independent API for external apps
  /board                        Board dependent files
  /common                       Misc architecture independent functions
  /disk                 Code for disk drive partition handling
  /doc                  Documentation (don't expect too much)
  /drivers              Commonly used device drivers
 +/dts                  Contains Makefile for building internal U-Boot fdt.
  /examples             Example code for standalone applications, etc.
  /fs                   Filesystem code (cramfs, ext2, jffs2, etc.)
  /include              Header Files
    /lzo                        Library files to support LZO decompression
  /net                  Networking code
  /post                 Power On Self Test
 -/rtc                  Real Time Clock drivers
 +/spl                  Secondary Program Loader framework
  /tools                        Tools to build S-Record or U-Boot images, etc.
  
  Software Configuration:
@@@ -251,29 -247,18 +251,29 @@@ Selection of Processor Architecture an
  ---------------------------------------------------
  
  For all supported boards there are ready-to-use default
 -configurations available; just type "make <board_name>_config".
 +configurations available; just type "make <board_name>_defconfig".
  
  Example: For a TQM823L module type:
  
        cd u-boot
 -      make TQM823L_config
 +      make TQM823L_defconfig
  
  For the Cogent platform, you need to specify the CPU type as well;
 -e.g. "make cogent_mpc8xx_config". And also configure the cogent
 +e.g. "make cogent_mpc8xx_defconfig". And also configure the cogent
  directory according to the instructions in cogent/README.
  
  
 +Sandbox Environment:
 +--------------------
 +
 +U-Boot can be built natively to run on a Linux host using the 'sandbox'
 +board. This allows feature development which is not board- or architecture-
 +specific to be undertaken on a native platform. The sandbox is also used to
 +run some of U-Boot's tests.
 +
 +See board/sandbox/README.sandbox for more details.
 +
 +
  Configuration Options:
  ----------------------
  
@@@ -320,11 -305,23 +320,11 @@@ The following options need to be config
                                          the LCD display every second with
                                          a "rotator" |\-/|\-/
  
 -- Board flavour: (if CONFIG_MPC8260ADS is defined)
 -              CONFIG_ADSTYPE
 -              Possible values are:
 -                      CONFIG_SYS_8260ADS      - original MPC8260ADS
 -                      CONFIG_SYS_8266ADS      - MPC8266ADS
 -                      CONFIG_SYS_PQ2FADS      - PQ2FADS-ZU or PQ2FADS-VR
 -                      CONFIG_SYS_8272ADS      - MPC8272ADS
 -
  - Marvell Family Member
                CONFIG_SYS_MVFS         - define it if you want to enable
                                          multiple fs option at one time
                                          for marvell soc family
  
 -- MPC824X Family Member (if CONFIG_MPC824X is defined)
 -              Define exactly one of
 -              CONFIG_MPC8240, CONFIG_MPC8245
 -
  - 8xx CPU Options: (if using an MPC8xx CPU)
                CONFIG_8xx_GCLK_FREQ    - deprecated: CPU clock if
                                          get_gclk_freq() cannot work
  
                CONFIG_A003399_NOR_WORKAROUND
                Enables a workaround for IFC erratum A003399. It is only
 -              requred during NOR boot.
 +              required during NOR boot.
 +
 +              CONFIG_A008044_WORKAROUND
 +              Enables a workaround for T1040/T1042 erratum A008044. It is only
 +              required during NAND boot and valid for Rev 1.0 SoC revision
  
                CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY
  
                This is the value to write into CCSR offset 0x18600
                according to the A004510 workaround.
  
 +              CONFIG_SYS_FSL_DSP_DDR_ADDR
 +              This value denotes start offset of DDR memory which is
 +              connected exclusively to the DSP cores.
 +
                CONFIG_SYS_FSL_DSP_M2_RAM_ADDR
                This value denotes start offset of M2 memory
                which is directly connected to the DSP core.
  
 +              CONFIG_SYS_FSL_DSP_M3_RAM_ADDR
 +              This value denotes start offset of M3 memory which is directly
 +              connected to the DSP core.
 +
                CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT
                This value denotes start offset of DSP CCSR space.
  
 +              CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
 +              Single Source Clock is clocking mode present in some of FSL SoC's.
 +              In this mode, a single differential clock is used to supply
 +              clocks to the sysclock, ddrclock and usbclock.
 +
 +              CONFIG_SYS_CPC_REINIT_F
 +              This CONFIG is defined when the CPC is configured as SRAM at the
 +              time of U-boot entry and is required to be re-initialized.
 +
 +              CONFIG_DEEP_SLEEP
 +              Indicates this SoC supports deep sleep feature. If deep sleep is
 +              supported, core will start to execute uboot when wakes up.
 +
  - Generic CPU options:
 +              CONFIG_SYS_GENERIC_GLOBAL_DATA
 +              Defines global data is initialized in generic board board_init_f().
 +              If this macro is defined, global data is created and cleared in
 +              generic board board_init_f(). Without this macro, architecture/board
 +              should initialize global data before calling board_init_f().
 +
                CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
  
                Defines the endianess of the CPU. Implementation of those
                values is arch specific.
  
 +              CONFIG_SYS_FSL_DDR
 +              Freescale DDR driver in use. This type of DDR controller is
 +              found in mpc83xx, mpc85xx, mpc86xx as well as some ARM core
 +              SoCs.
 +
 +              CONFIG_SYS_FSL_DDR_ADDR
 +              Freescale DDR memory-mapped register base.
 +
 +              CONFIG_SYS_FSL_DDR_EMU
 +              Specify emulator support for DDR. Some DDR features such as
 +              deskew training are not available.
 +
 +              CONFIG_SYS_FSL_DDRC_GEN1
 +              Freescale DDR1 controller.
 +
 +              CONFIG_SYS_FSL_DDRC_GEN2
 +              Freescale DDR2 controller.
 +
 +              CONFIG_SYS_FSL_DDRC_GEN3
 +              Freescale DDR3 controller.
 +
 +              CONFIG_SYS_FSL_DDRC_GEN4
 +              Freescale DDR4 controller.
 +
 +              CONFIG_SYS_FSL_DDRC_ARM_GEN3
 +              Freescale DDR3 controller for ARM-based SoCs.
 +
 +              CONFIG_SYS_FSL_DDR1
 +              Board config to use DDR1. It can be enabled for SoCs with
 +              Freescale DDR1 or DDR2 controllers, depending on the board
 +              implemetation.
 +
 +              CONFIG_SYS_FSL_DDR2
 +              Board config to use DDR2. It can be eanbeld for SoCs with
 +              Freescale DDR2 or DDR3 controllers, depending on the board
 +              implementation.
 +
 +              CONFIG_SYS_FSL_DDR3
 +              Board config to use DDR3. It can be enabled for SoCs with
 +              Freescale DDR3 or DDR3L controllers.
 +
 +              CONFIG_SYS_FSL_DDR3L
 +              Board config to use DDR3L. It can be enabled for SoCs with
 +              DDR3L controllers.
 +
 +              CONFIG_SYS_FSL_DDR4
 +              Board config to use DDR4. It can be enabled for SoCs with
 +              DDR4 controllers.
 +
 +              CONFIG_SYS_FSL_IFC_BE
 +              Defines the IFC controller register space as Big Endian
 +
 +              CONFIG_SYS_FSL_IFC_LE
 +              Defines the IFC controller register space as Little Endian
 +
 +              CONFIG_SYS_FSL_PBL_PBI
 +              It enables addition of RCW (Power on reset configuration) in built image.
 +              Please refer doc/README.pblimage for more details
 +
 +              CONFIG_SYS_FSL_PBL_RCW
 +              It adds PBI(pre-boot instructions) commands in u-boot build image.
 +              PBI commands can be used to configure SoC before it starts the execution.
 +              Please refer doc/README.pblimage for more details
 +
 +              CONFIG_SPL_FSL_PBL
 +              It adds a target to create boot binary having SPL binary in PBI format
 +              concatenated with u-boot binary.
 +
 +              CONFIG_SYS_FSL_DDR_BE
 +              Defines the DDR controller register space as Big Endian
 +
 +              CONFIG_SYS_FSL_DDR_LE
 +              Defines the DDR controller register space as Little Endian
 +
 +              CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY
 +              Physical address from the view of DDR controllers. It is the
 +              same as CONFIG_SYS_DDR_SDRAM_BASE for  all Power SoCs. But
 +              it could be different for ARM SoCs.
 +
 +              CONFIG_SYS_FSL_DDR_INTLV_256B
 +              DDR controller interleaving on 256-byte. This is a special
 +              interleaving mode, handled by Dickens for Freescale layerscape
 +              SoCs with ARM core.
 +
 +              CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS
 +              Number of controllers used as main memory.
 +
 +              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
  
                CONFIG_ARM_ERRATA_742230
                CONFIG_ARM_ERRATA_743622
                CONFIG_ARM_ERRATA_751472
 +              CONFIG_ARM_ERRATA_794072
 +              CONFIG_ARM_ERRATA_761320
  
                If set, the workarounds for these ARM errata are applied early
                during U-Boot startup. Note that these options force the
                exists, unlike the similar options in the Linux kernel. Do not
                set these options unless they apply!
  
 -- CPU timer options:
 -              CONFIG_SYS_HZ
 +- Driver Model
 +              Driver model is a new framework for devices in U-Boot
 +              introduced in early 2014. U-Boot is being progressively
 +              moved over to this. It offers a consistent device structure,
 +              supports grouping devices into classes and has built-in
 +              handling of platform data and device tree.
 +
 +              To enable transition to driver model in a relatively
 +              painful fashion, each subsystem can be independently
 +              switched between the legacy/ad-hoc approach and the new
 +              driver model using the options below. Also, many uclass
 +              interfaces include compatibility features which may be
 +              removed once the conversion of that subsystem is complete.
 +              As a result, the API provided by the subsystem may in fact
 +              not change with driver model.
 +
 +              See doc/driver-model/README.txt for more information.
 +
 +              CONFIG_DM
 +
 +              Enable driver model. This brings in the core support,
 +              including scanning of platform data on start-up. If
 +              CONFIG_OF_CONTROL is enabled, the device tree will be
 +              scanned also when available.
 +
 +              CONFIG_CMD_DM
 +
 +              Enable driver model test commands. These allow you to print
 +              out the driver model tree and the uclasses.
 +
 +              CONFIG_DM_DEMO
 +
 +              Enable some demo devices and the 'demo' command. These are
 +              really only useful for playing around while trying to
 +              understand driver model in sandbox.
 +
 +              CONFIG_SPL_DM
 +
 +              Enable driver model in SPL. You will need to provide a
 +              suitable malloc() implementation. If you are not using the
 +              full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START,
 +              consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you
 +              must provide CONFIG_SYS_MALLOC_F_LEN to set the size.
 +              In most cases driver model will only allocate a few uclasses
 +              and devices in SPL, so 1KB should be enable. See
 +              CONFIG_SYS_MALLOC_F_LEN for more details on how to enable
 +              it.
 +
 +              CONFIG_DM_SERIAL
 +
 +              Enable driver model for serial. This replaces
 +              drivers/serial/serial.c with the serial uclass, which
 +              implements serial_putc() etc. The uclass interface is
 +              defined in include/serial.h.
 +
 +              CONFIG_DM_GPIO
 +
 +              Enable driver model for GPIO access. The standard GPIO
 +              interface (gpio_get_value(), etc.) is then implemented by
 +              the GPIO uclass. Drivers provide methods to query the
 +              particular GPIOs that they provide. The uclass interface
 +              is defined in include/asm-generic/gpio.h.
 +
 +              CONFIG_DM_SPI
 +
 +              Enable driver model for SPI. The SPI slave interface
 +              (spi_setup_slave(), spi_xfer(), etc.) is then implemented by
 +              the SPI uclass. Drivers provide methods to access the SPI
 +              buses that they control. The uclass interface is defined in
 +              include/spi.h. The existing spi_slave structure is attached
 +              as 'parent data' to every slave on each bus. Slaves
 +              typically use driver-private data instead of extending the
 +              spi_slave structure.
 +
 +              CONFIG_DM_SPI_FLASH
 +
 +              Enable driver model for SPI flash. This SPI flash interface
 +              (spi_flash_probe(), spi_flash_write(), etc.) is then
 +              implemented by the SPI flash uclass. There is one standard
 +              SPI flash driver which knows how to probe most chips
 +              supported by U-Boot. The uclass interface is defined in
 +              include/spi_flash.h, but is currently fully compatible
 +              with the old interface to avoid confusion and duplication
 +              during the transition parent. SPI and SPI flash must be
 +              enabled together (it is not possible to use driver model
 +              for one and not the other).
 +
 +              CONFIG_DM_CROS_EC
 +
 +              Enable driver model for the Chrome OS EC interface. This
 +              allows the cros_ec SPI driver to operate with CONFIG_DM_SPI
 +              but otherwise makes few changes. Since cros_ec also supports
 +              I2C and LPC (which don't support driver model yet), a full
 +              conversion is not yet possible.
 +
 +
 +              ** Code size options: The following options are enabled by
 +              default except in SPL. Enable them explicitly to get these
 +              features in SPL.
 +
 +              CONFIG_DM_WARN
 +
 +              Enable the dm_warn() function. This can use up quite a bit
 +              of space for its strings.
 +
 +              CONFIG_DM_STDIO
 +
 +              Enable registering a serial device with the stdio library.
 +
 +              CONFIG_DM_DEVICE_REMOVE
 +
 +              Enable removing of devices.
  
 -              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
  
                CONFIG_MEMSIZE_IN_BYTES         [relevant for MIPS only]
  
 -              When transferring memsize parameter to linux, some versions
 +              When transferring memsize parameter to Linux, some versions
                expect it to be in bytes, others in MB.
                Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes.
  
                Board code has addition modification that it wants to make
                to the flat device tree before handing it off to the kernel
  
 +              CONFIG_OF_SYSTEM_SETUP
 +
 +              Other code has addition modification that it wants to make
 +              to the flat device tree before handing it off to the kernel.
 +              This causes ft_system_setup() to be called before booting
 +              the kernel.
 +
                CONFIG_OF_BOOT_CPU
  
                This define fills in the correct boot CPU in the boot
                boot loader that has already initialized the UART.  Define this
                variable to flush the UART at init time.
  
 +              CONFIG_SERIAL_HW_FLOW_CONTROL
 +
 +              Define this variable to enable hw flow control in serial driver.
 +              Current user of this option is drivers/serial/nsl16550.c driver
  
  - Console Interface:
                Depending on board, define exactly one serial port
                the "silent" environment variable. See
                doc/README.silent for more information.
  
 +              CONFIG_SYS_CONSOLE_BG_COL: define the backgroundcolor, default
 +                      is 0x00.
 +              CONFIG_SYS_CONSOLE_FG_COL: define the foregroundcolor, default
 +                      is 0xa0.
 +
  - Console Baudrate:
                CONFIG_BAUDRATE - in bps
                Select one of the baudrates listed in
                as a convenience, when switching between booting from
                RAM and NFS.
  
 +- Bootcount:
 +              CONFIG_BOOTCOUNT_LIMIT
 +              Implements a mechanism for detecting a repeating reboot
 +              cycle, see:
 +              http://www.denx.de/wiki/view/DULG/UBootBootCountLimit
 +
 +              CONFIG_BOOTCOUNT_ENV
 +              If no softreset save registers are found on the hardware
 +              "bootcount" is stored in the environment. To prevent a
 +              saveenv on all reboots, the environment variable
 +              "upgrade_available" is used. If "upgrade_available" is
 +              0, "bootcount" is always 0, if "upgrade_available" is
 +              1 "bootcount" is incremented in the environment.
 +              So the Userspace Applikation must set the "upgrade_available"
 +              and "bootcount" variable to 0, if a boot was successfully.
 +
  - Pre-Boot Commands:
                CONFIG_PREBOOT
  
                The default command configuration includes all commands
                except those marked below with a "*".
  
 +              CONFIG_CMD_AES            AES 128 CBC encrypt/decrypt
                CONFIG_CMD_ASKENV       * ask for env variable
                CONFIG_CMD_BDI            bdinfo
                CONFIG_CMD_BEDBUG       * Include BedBug Debugger
                CONFIG_CMD_BMP          * BMP support
                CONFIG_CMD_BSP          * Board specific commands
                CONFIG_CMD_BOOTD          bootd
 +              CONFIG_CMD_BOOTI        * ARM64 Linux kernel Image support
                CONFIG_CMD_CACHE        * icache, dcache
 +              CONFIG_CMD_CLK          * clock command support
                CONFIG_CMD_CONSOLE        coninfo
                CONFIG_CMD_CRC32        * crc32
                CONFIG_CMD_DATE         * support for RTC, date/time...
                CONFIG_CMD_ELF          * bootelf, bootvx
                CONFIG_CMD_ENV_CALLBACK * display details about env callbacks
                CONFIG_CMD_ENV_FLAGS    * display details about env flags
 +              CONFIG_CMD_ENV_EXISTS   * check existence of env variable
                CONFIG_CMD_EXPORTENV    * export the environment
                CONFIG_CMD_EXT2         * ext2 command support
                CONFIG_CMD_EXT4         * ext4 command support
 +              CONFIG_CMD_FS_GENERIC   * filesystem commands (e.g. load, ls)
 +                                        that work for multiple fs types
 +              CONFIG_CMD_FS_UUID      * Look up a filesystem UUID
                CONFIG_CMD_SAVEENV        saveenv
                CONFIG_CMD_FDC          * Floppy Disk Support
                CONFIG_CMD_FAT          * FAT command support
 -              CONFIG_CMD_FDOS         * Dos diskette Support
                CONFIG_CMD_FLASH          flinfo, erase, protect
                CONFIG_CMD_FPGA           FPGA device initialization support
                CONFIG_CMD_FUSE         * Device fuse support
                CONFIG_CMD_IMLS           List all images found in NOR flash
                CONFIG_CMD_IMLS_NAND    * List all images found in NAND flash
                CONFIG_CMD_IMMAP        * IMMR dump support
 +              CONFIG_CMD_IOTRACE      * I/O tracing for debugging
                CONFIG_CMD_IMPORTENV    * import an environment
                CONFIG_CMD_INI          * import data from an ini file into the env
                CONFIG_CMD_IRQ          * irqinfo
                CONFIG_CMD_CDP          * Cisco Discover Protocol support
                CONFIG_CMD_MFSL         * Microblaze FSL support
                CONFIG_CMD_XIMG           Load part of Multi Image
 -
 +              CONFIG_CMD_UUID         * Generate random UUID or GUID string
  
                EXAMPLE: If you want all functions except of network
                support you can write:
  
  - Regular expression support:
                CONFIG_REGEX
 -                If this variable is defined, U-Boot is linked against
 -                the SLRE (Super Light Regular Expression) library,
 -                which adds regex support to some commands, as for
 -                example "env grep" and "setexpr".
 +              If this variable is defined, U-Boot is linked against
 +              the SLRE (Super Light Regular Expression) library,
 +              which adds regex support to some commands, as for
 +              example "env grep" and "setexpr".
  
  - Device tree:
                CONFIG_OF_CONTROL
                CONFIG_RTC_DS1307       - use Maxim, Inc. DS1307 RTC
                CONFIG_RTC_DS1337       - use Maxim, Inc. DS1337 RTC
                CONFIG_RTC_DS1338       - use Maxim, Inc. DS1338 RTC
 +              CONFIG_RTC_DS1339       - use Maxim, Inc. DS1339 RTC
                CONFIG_RTC_DS164x       - use Dallas DS164x RTC
                CONFIG_RTC_ISL1208      - use Intersil ISL1208 RTC
                CONFIG_RTC_MAX6900      - use Maxim, Inc. MAX6900 RTC
  
  - GPIO Support:
                CONFIG_PCA953X          - use NXP's PCA953X series I2C GPIO
 -              CONFIG_PCA953X_INFO     - enable pca953x info command
  
                The CONFIG_SYS_I2C_PCA953X_WIDTH option specifies a list of
                chip-ngpio pairs that tell the PCA953X driver the number of
                Note that if the GPIO device uses I2C, then the I2C interface
                must also be configured. See I2C Support, below.
  
 +- I/O tracing:
 +              When CONFIG_IO_TRACE is selected, U-Boot intercepts all I/O
 +              accesses and can checksum them or write a list of them out
 +              to memory. See the 'iotrace' command for details. This is
 +              useful for testing device drivers since it can confirm that
 +              the driver behaves the same way before and after a code
 +              change. Currently this is supported on sandbox and arm. To
 +              add support for your architecture, add '#include <iotrace.h>'
 +              to the bottom of arch/<arch>/include/asm/io.h and test.
 +
 +              Example output from the 'iotrace stats' command is below.
 +              Note that if the trace buffer is exhausted, the checksum will
 +              still continue to operate.
 +
 +                      iotrace is enabled
 +                      Start:  10000000        (buffer start address)
 +                      Size:   00010000        (buffer size)
 +                      Offset: 00000120        (current buffer offset)
 +                      Output: 10000120        (start + offset)
 +                      Count:  00000018        (number of trace records)
 +                      CRC32:  9526fb66        (CRC32 of all trace records)
 +
  - Timestamp Support:
  
                When CONFIG_TIMESTAMP is selected, the timestamp
                devices.
                CONFIG_SYS_SCSI_SYM53C8XX_CCF to fix clock timing (80Mhz)
  
 -                The environment variable 'scsidevs' is set to the number of
 -                SCSI devices found during the last scan.
 +              The environment variable 'scsidevs' is set to the number of
 +              SCSI devices found during the last scan.
  
  - NETWORK Support (PCI):
                CONFIG_E1000
                        CONFIG_SH_ETHER_CACHE_WRITEBACK
                        If this option is set, the driver enables cache flush.
  
 +- PWM Support:
 +              CONFIG_PWM_IMX
 +              Support for PWM modul on the imx6.
 +
  - TPM Support:
                CONFIG_TPM
                Support TPM devices.
                CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
                txfilltuning field in the EHCI controller on reset.
  
 -              CONFIG_USB_HUB_MIN_POWER_ON_DELAY defines the minimum
 -              interval for usb hub power-on delay.(minimum 100msec)
 +              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.
                        CONFIG_SH_MMCIF_CLK
                        Define the clock frequency for MMCIF
  
 +              CONFIG_GENERIC_MMC
 +              Enable the generic MMC driver
 +
 +              CONFIG_SUPPORT_EMMC_BOOT
 +              Enable some additional features of the eMMC boot partitions.
 +
 +              CONFIG_SUPPORT_EMMC_RPMB
 +              Enable the commands for reading, writing and programming the
 +              key for the Replay Protection Memory Block partition in eMMC.
 +
  - USB Device Firmware Update (DFU) class support:
                CONFIG_DFU_FUNCTION
                This enables the USB portion of the DFU USB class
                CONFIG_DFU_NAND
                This enables support for exposing NAND devices via DFU.
  
 +              CONFIG_DFU_RAM
 +              This enables support for exposing RAM via DFU.
 +              Note: DFU spec refer to non-volatile memory usage, but
 +              allow usages beyond the scope of spec - here RAM usage,
 +              one that would help mostly the developer.
 +
                CONFIG_SYS_DFU_DATA_BUF_SIZE
                Dfu transfer uses a buffer before writing data to the
                raw storage device. Make the size (in bytes) of this buffer
                this to the maximum filesize (in bytes) for the buffer.
                Default is 4 MiB if undefined.
  
 +              DFU_DEFAULT_POLL_TIMEOUT
 +              Poll timeout [ms], is the timeout a device can send to the
 +              host. The host must wait for this timeout before sending
 +              a subsequent DFU_GET_STATUS request to the device.
 +
 +              DFU_MANIFEST_POLL_TIMEOUT
 +              Poll timeout [ms], which the device sends to the host when
 +              entering dfuMANIFEST state. Host waits this timeout, before
 +              sending again an USB request to the device.
 +
 +- USB Device Android Fastboot support:
 +              CONFIG_CMD_FASTBOOT
 +              This enables the command "fastboot" which enables the Android
 +              fastboot mode for the platform's USB device. Fastboot is a USB
 +              protocol for downloading images, flashing and device control
 +              used on Android devices.
 +              See doc/README.android-fastboot for more information.
 +
 +              CONFIG_ANDROID_BOOT_IMAGE
 +              This enables support for booting images which use the Android
 +              image format header.
 +
 +              CONFIG_USB_FASTBOOT_BUF_ADDR
 +              The fastboot protocol requires a large memory buffer for
 +              downloads. Define this to the starting RAM address to use for
 +              downloaded images.
 +
 +              CONFIG_USB_FASTBOOT_BUF_SIZE
 +              The fastboot protocol requires a large memory buffer for
 +              downloads. This buffer should be as large as possible for a
 +              platform. Define this to the size available RAM for fastboot.
 +
 +              CONFIG_FASTBOOT_FLASH
 +              The fastboot protocol includes a "flash" command for writing
 +              the downloaded image to a non-volatile storage device. Define
 +              this to enable the "fastboot flash" command.
 +
 +              CONFIG_FASTBOOT_FLASH_MMC_DEV
 +              The fastboot "flash" command requires additional information
 +              regarding the non-volatile storage device. Define this to
 +              the eMMC device that fastboot should use to store the image.
 +
 +              CONFIG_FASTBOOT_GPT_NAME
 +              The fastboot "flash" command supports writing the downloaded
 +              image to the Protective MBR and the Primary GUID Partition
 +              Table. (Additionally, this downloaded image is post-processed
 +              to generate and write the Backup GUID Partition Table.)
 +              This occurs when the specified "partition name" on the
 +              "fastboot flash" command line matches this value.
 +              Default is GPT_ENTRY_NAME (currently "gpt") if undefined.
 +
  - Journaling Flash filesystem support:
                CONFIG_JFFS2_NAND, CONFIG_JFFS2_NAND_OFF, CONFIG_JFFS2_NAND_SIZE,
                CONFIG_JFFS2_NAND_DEV
@@@ -1811,12 -1440,6 +1811,12 @@@ CBFS (Coreboot Filesystem) suppor
                filesystem. Available commands are cbfsinit, cbfsinfo, cbfsls
                and cbfsload.
  
 +- FAT(File Allocation Table) filesystem cluster size:
 +              CONFIG_FS_FAT_MAX_CLUSTSIZE
 +
 +              Define the max cluster size for fat operations else
 +              a default value of 65536 will be defined.
 +
  - Keyboard Support:
                CONFIG_ISA_KEYBOARD
  
  
                CONFIG_LCD_ALIGNMENT
  
 -              Normally the LCD is page-aligned (tyically 4KB). If this is
 +              Normally the LCD is page-aligned (typically 4KB). If this is
                defined then the LCD will be aligned to this value instead.
                For ARM it is sometimes useful to use MMU_SECTION_SIZE
                here, since it is cheaper to change data cache settings on
  
                If this option is set, then U-Boot will prevent the environment
                variable "splashimage" from being set to a problematic address
 -              (see README.displaying-bmps and README.arm-unaligned-accesses).
 +              (see README.displaying-bmps).
                This option is useful for targets where, due to alignment
                restrictions, an improperly aligned BMP image will cause a data
                abort. If you think you will not have problems with unaligned
                can be displayed via the splashscreen support or the
                bmp command.
  
 -- Do compresssing for memory range:
 +- Do compressing for memory range:
                CONFIG_CMD_ZIP
  
                If this option is set, it would use zlib deflate method
                to compress the specified memory at its best effort.
  
  - Compression support:
 +              CONFIG_GZIP
 +
 +              Enabled by default to support gzip compressed images.
 +
                CONFIG_BZIP2
  
                If this option is set, support for bzip2 compressed
                then calculate the amount of needed dynamic memory (ensuring
                the appropriate CONFIG_SYS_MALLOC_LEN value).
  
 +              CONFIG_LZO
 +
 +              If this option is set, support for LZO compressed images
 +              is included.
 +
  - MII/PHY support:
                CONFIG_PHY_ADDR
  
                4th and following
                BOOTP requests:         delay 0 ... 8 sec
  
 +              CONFIG_BOOTP_ID_CACHE_SIZE
 +
 +              BOOTP packets are uniquely identified using a 32-bit ID. The
 +              server will copy the ID from client requests to responses and
 +              U-Boot will use this to determine if it is the destination of
 +              an incoming response. Some servers will check that addresses
 +              aren't in use before handing them out (usually using an ARP
 +              ping) and therefore take up to a few hundred milliseconds to
 +              respond. Network congestion may also influence the time it
 +              takes for a response to make it back to the client. If that
 +              time is too long, U-Boot will retransmit requests. In order
 +              to allow earlier responses to still be accepted after these
 +              retransmissions, U-Boot's BOOTP client keeps a small cache of
 +              IDs. The CONFIG_BOOTP_ID_CACHE_SIZE controls the size of this
 +              cache. The default is to keep IDs for up to four outstanding
 +              requests. Increasing this will allow U-Boot to accept offers
 +              from a BOOTP client in networks with unusually high latency.
 +
+ - BOOTP Random transaction ID:
+               CONFIG_BOOTP_RANDOM_ID
+               The standard algorithm to generate a DHCP/BOOTP transaction ID
+               by using the MAC address and the current time stamp may not
+               quite unlikely produce duplicate transaction IDs from different
+               clients in the same network. This option creates a transaction
+               ID using the rand() function. Provided that the RNG has been
+               seeded well, this should guarantee unique transaction IDs
+               always.
  - DHCP Advanced Options:
                You can fine tune the DHCP functionality by defining
                CONFIG_BOOTP_* symbols:
                kernel). Defining CONFIG_STATUS_LED enables this
                feature in U-Boot.
  
 +              Additional options:
 +
 +              CONFIG_GPIO_LED
 +              The status LED can be connected to a GPIO pin.
 +              In such cases, the gpio_led driver can be used as a
 +              status LED backend implementation. Define CONFIG_GPIO_LED
 +              to include the gpio_led driver in the U-Boot binary.
 +
 +              CONFIG_GPIO_LED_INVERTED_TABLE
 +              Some GPIO connected LEDs may have inverted polarity in which
 +              case the GPIO high value corresponds to LED off state and
 +              GPIO low value corresponds to LED on state.
 +              In such cases CONFIG_GPIO_LED_INVERTED_TABLE may be defined
 +              with a list of GPIO LEDs that have inverted polarity.
 +
  - CAN Support:        CONFIG_CAN_DRIVER
  
                Defining CONFIG_CAN_DRIVER enables CAN driver support
                    offset CONFIG_SYS_FSL_I2C_SPEED for the i2c speed and
                    CONFIG_SYS_FSL_I2C_SLAVE for the slave addr of the first
                    bus.
 -                  - If your board supports a second fsl i2c bus, define
 +                - If your board supports a second fsl i2c bus, define
                    CONFIG_SYS_FSL_I2C2_OFFSET for the register offset
                    CONFIG_SYS_FSL_I2C2_SPEED for the speed and
                    CONFIG_SYS_FSL_I2C2_SLAVE for the slave address of the
                    second bus.
  
                - drivers/i2c/tegra_i2c.c:
 -               - activate this driver with CONFIG_SYS_I2C_TEGRA
 -               - This driver adds 4 i2c buses with a fix speed from
 -                 100000 and the slave addr 0!
 +                - activate this driver with CONFIG_SYS_I2C_TEGRA
 +                - This driver adds 4 i2c buses with a fix speed from
 +                  100000 and the slave addr 0!
  
                - drivers/i2c/ppc4xx_i2c.c
                  - activate this driver with CONFIG_SYS_I2C_PPC4XX
                  - CONFIG_SYS_I2C_PPC4XX_CH0 activate hardware channel 0
                  - CONFIG_SYS_I2C_PPC4XX_CH1 activate hardware channel 1
  
 +              - drivers/i2c/i2c_mxc.c
 +                - activate this driver with CONFIG_SYS_I2C_MXC
 +                - define speed for bus 1 with CONFIG_SYS_MXC_I2C1_SPEED
 +                - define slave for bus 1 with CONFIG_SYS_MXC_I2C1_SLAVE
 +                - define speed for bus 2 with CONFIG_SYS_MXC_I2C2_SPEED
 +                - define slave for bus 2 with CONFIG_SYS_MXC_I2C2_SLAVE
 +                - define speed for bus 3 with CONFIG_SYS_MXC_I2C3_SPEED
 +                - define slave for bus 3 with CONFIG_SYS_MXC_I2C3_SLAVE
 +              If those defines are not set, default value is 100000
 +              for speed, and 0 for slave.
 +
 +              - drivers/i2c/rcar_i2c.c:
 +                - activate this driver with CONFIG_SYS_I2C_RCAR
 +                - This driver adds 4 i2c buses
 +
 +                - CONFIG_SYS_RCAR_I2C0_BASE for setting the register channel 0
 +                - CONFIG_SYS_RCAR_I2C0_SPEED for for the speed channel 0
 +                - CONFIG_SYS_RCAR_I2C1_BASE for setting the register channel 1
 +                - CONFIG_SYS_RCAR_I2C1_SPEED for for the speed channel 1
 +                - CONFIG_SYS_RCAR_I2C2_BASE for setting the register channel 2
 +                - CONFIG_SYS_RCAR_I2C2_SPEED for for the speed channel 2
 +                - CONFIG_SYS_RCAR_I2C3_BASE for setting the register channel 3
 +                - CONFIG_SYS_RCAR_I2C3_SPEED for for the speed channel 3
 +                - CONFIF_SYS_RCAR_I2C_NUM_CONTROLLERS for number of i2c buses
 +
 +              - drivers/i2c/sh_i2c.c:
 +                - activate this driver with CONFIG_SYS_I2C_SH
 +                - This driver adds from 2 to 5 i2c buses
 +
 +                - CONFIG_SYS_I2C_SH_BASE0 for setting the register channel 0
 +                - CONFIG_SYS_I2C_SH_SPEED0 for for the speed channel 0
 +                - CONFIG_SYS_I2C_SH_BASE1 for setting the register channel 1
 +                - CONFIG_SYS_I2C_SH_SPEED1 for for the speed channel 1
 +                - CONFIG_SYS_I2C_SH_BASE2 for setting the register channel 2
 +                - CONFIG_SYS_I2C_SH_SPEED2 for for the speed channel 2
 +                - CONFIG_SYS_I2C_SH_BASE3 for setting the register channel 3
 +                - CONFIG_SYS_I2C_SH_SPEED3 for for the speed channel 3
 +                - CONFIG_SYS_I2C_SH_BASE4 for setting the register channel 4
 +                - CONFIG_SYS_I2C_SH_SPEED4 for for the speed channel 4
 +                - CONFIG_SYS_I2C_SH_BASE5 for setting the register channel 5
 +                - CONFIG_SYS_I2C_SH_SPEED5 for for the speed channel 5
 +                - CONFIG_SYS_I2C_SH_NUM_CONTROLLERS for number of i2c buses
 +
 +              - drivers/i2c/omap24xx_i2c.c
 +                - activate this driver with CONFIG_SYS_I2C_OMAP24XX
 +                - CONFIG_SYS_OMAP24_I2C_SPEED speed channel 0
 +                - CONFIG_SYS_OMAP24_I2C_SLAVE slave addr channel 0
 +                - CONFIG_SYS_OMAP24_I2C_SPEED1 speed channel 1
 +                - CONFIG_SYS_OMAP24_I2C_SLAVE1 slave addr channel 1
 +                - CONFIG_SYS_OMAP24_I2C_SPEED2 speed channel 2
 +                - CONFIG_SYS_OMAP24_I2C_SLAVE2 slave addr channel 2
 +                - CONFIG_SYS_OMAP24_I2C_SPEED3 speed channel 3
 +                - CONFIG_SYS_OMAP24_I2C_SLAVE3 slave addr channel 3
 +                - CONFIG_SYS_OMAP24_I2C_SPEED4 speed channel 4
 +                - CONFIG_SYS_OMAP24_I2C_SLAVE4 slave addr channel 4
 +
 +              - drivers/i2c/zynq_i2c.c
 +                - activate this driver with CONFIG_SYS_I2C_ZYNQ
 +                - set CONFIG_SYS_I2C_ZYNQ_SPEED for speed setting
 +                - set CONFIG_SYS_I2C_ZYNQ_SLAVE for slave addr
 +
 +              - drivers/i2c/s3c24x0_i2c.c:
 +                - activate this driver with CONFIG_SYS_I2C_S3C24X0
 +                - This driver adds i2c buses (11 for Exynos5250, Exynos5420
 +                  9 i2c buses for Exynos4 and 1 for S3C24X0 SoCs from Samsung)
 +                  with a fix speed from 100000 and the slave addr 0!
 +
 +              - drivers/i2c/ihs_i2c.c
 +                - activate this driver with CONFIG_SYS_I2C_IHS
 +                - CONFIG_SYS_I2C_IHS_CH0 activate hardware channel 0
 +                - CONFIG_SYS_I2C_IHS_SPEED_0 speed channel 0
 +                - CONFIG_SYS_I2C_IHS_SLAVE_0 slave addr channel 0
 +                - CONFIG_SYS_I2C_IHS_CH1 activate hardware channel 1
 +                - CONFIG_SYS_I2C_IHS_SPEED_1 speed channel 1
 +                - CONFIG_SYS_I2C_IHS_SLAVE_1 slave addr channel 1
 +                - CONFIG_SYS_I2C_IHS_CH2 activate hardware channel 2
 +                - CONFIG_SYS_I2C_IHS_SPEED_2 speed channel 2
 +                - CONFIG_SYS_I2C_IHS_SLAVE_2 slave addr channel 2
 +                - CONFIG_SYS_I2C_IHS_CH3 activate hardware channel 3
 +                - CONFIG_SYS_I2C_IHS_SPEED_3 speed channel 3
 +                - CONFIG_SYS_I2C_IHS_SLAVE_3 slave addr channel 3
 +
                additional defines:
  
                CONFIG_SYS_NUM_I2C_BUSES
 -              Hold the number of i2c busses you want to use. If you
 +              Hold the number of i2c buses you want to use. If you
                don't use/have i2c muxes on your i2c bus, this
                is equal to CONFIG_SYS_NUM_I2C_ADAPTERS, and you can
                omit this define.
                define.
  
                CONFIG_SYS_I2C_BUSES
 -              hold a list of busses you want to use, only used if
 +              hold a list of buses you want to use, only used if
                CONFIG_SYS_I2C_DIRECT_BUS is not defined, for example
                a board with CONFIG_SYS_I2C_MAX_HOPS = 1 and
                CONFIG_SYS_NUM_I2C_BUSES = 9:
                Enables the driver for the SPI controllers on i.MX and MXC
                SoCs. Currently i.MX31/35/51 are supported.
  
 +              CONFIG_SYS_SPI_MXC_WAIT
 +              Timeout for waiting until spi transfer completed.
 +              default: (CONFIG_SYS_HZ/100)     /* 10 ms */
 +
  - FPGA Support: CONFIG_FPGA
  
                Enables FPGA subsystem.
  
                Specify the number of FPGA devices to support.
  
 +              CONFIG_CMD_FPGA_LOADMK
 +
 +              Enable support for fpga loadmk command
 +
 +              CONFIG_CMD_FPGA_LOADP
 +
 +              Enable support for fpga loadp command - load partial bitstream
 +
 +              CONFIG_CMD_FPGA_LOADBP
 +
 +              Enable support for fpga loadbp command - load partial bitstream
 +              (Xilinx only)
 +
                CONFIG_SYS_FPGA_PROG_FEEDBACK
  
                Enable printing of hash marks during FPGA configuration.
  
                CONFIG_SYS_FPGA_WAIT_INIT
  
 -              Maximum time to wait for the INIT_B line to deassert
 -              after PROB_B has been deasserted during a Virtex II
 +              Maximum time to wait for the INIT_B line to de-assert
 +              after PROB_B has been de-asserted during a Virtex II
                FPGA configuration sequence. The default time is 500
                ms.
  
                CONFIG_SYS_FPGA_WAIT_BUSY
  
 -              Maximum time to wait for BUSY to deassert during
 +              Maximum time to wait for BUSY to de-assert during
                Virtex II FPGA configuration. The default is 5 ms.
  
                CONFIG_SYS_FPGA_WAIT_CONFIG
                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
  
                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
 -              Busybox) as command line interpreter, thus enabling
 -              powerful command line syntax like
 -              if...then...else...fi conditionals or `&&' and '||'
 -              constructs ("shell scripts").
 -
 -              If undefined, you get the old, much simpler behaviour
 -              with a somewhat smaller memory footprint.
 -
 -
                CONFIG_SYS_PROMPT_HUSH_PS2
  
                This defines the secondary prompt string, which is
                of the backslashes before semicolons and special
                symbols.
  
 -- Commandline Editing and History:
 +- Command Line Editing and History:
                CONFIG_CMDLINE_EDITING
  
                Enable editing and History functions for interactive
 -              commandline input operations
 +              command line input operations
  
  - Default Environment:
                CONFIG_EXTRA_ENV_SETTINGS
                CONFIG_DELAY_ENVIRONMENT
  
                Normally the environment is loaded when the board is
 -              intialised so that it is available to U-Boot. This inhibits
 +              initialised so that it is available to U-Boot. This inhibits
                that so that the environment is not available until
                explicitly loaded later by U-Boot code. With CONFIG_OF_CONTROL
                this is instead controlled by the value of
                Define this option to use the Bank addr/Extended addr
                support on SPI flashes which has size > 16Mbytes.
  
 +              CONFIG_SF_DUAL_FLASH            Dual flash memories
 +
 +              Define this option to use dual flash support where two flash
 +              memories can be connected with a given cs line.
 +              Currently Xilinx Zynq qspi supports these type of connections.
 +
 +              CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
 +              enable the W#/Vpp signal to disable writing to the status
 +              register on ST MICRON flashes like the N25Q128.
 +              The status register write enable/disable bit, combined with
 +              the W#/VPP signal provides hardware data protection for the
 +              device as follows: When the enable/disable bit is set to 1,
 +              and the W#/VPP signal is driven LOW, the status register
 +              nonvolatile bits become read-only and the WRITE STATUS REGISTER
 +              operation will not execute. The only way to exit this
 +              hardware-protected mode is to drive W#/VPP HIGH.
 +
  - SystemACE Support:
                CONFIG_SYSTEMACE
  
                Note: There is also a sha1sum command, which should perhaps
                be deprecated in favour of 'hash sha1'.
  
 +- Freescale i.MX specific commands:
 +              CONFIG_CMD_HDMIDETECT
 +              This enables 'hdmidet' command which returns true if an
 +              HDMI monitor is detected.  This command is i.MX 6 specific.
 +
 +              CONFIG_CMD_BMODE
 +              This enables the 'bmode' (bootmode) command for forcing
 +              a boot from specific media.
 +
 +              This is useful for forcing the ROM's usb downloader to
 +              activate upon a watchdog reset which is nice when iterating
 +              on U-Boot.  Using the reset button or running bmode normal
 +              will set it back to normal.  This command currently
 +              supports i.MX53 and i.MX6.
 +
  - Signing support:
                CONFIG_RSA
  
                This enables the RSA algorithm used for FIT image verification
 -              in U-Boot. See doc/uImage/signature for more information.
 +              in U-Boot. See doc/uImage.FIT/signature.txt for more information.
  
                The signing part is build into mkimage regardless of this
                option.
  
 +- bootcount support:
 +              CONFIG_BOOTCOUNT_LIMIT
 +
 +              This enables the bootcounter support, see:
 +              http://www.denx.de/wiki/DULG/UBootBootCountLimit
 +
 +              CONFIG_AT91SAM9XE
 +              enable special bootcounter support on at91sam9xe based boards.
 +              CONFIG_BLACKFIN
 +              enable special bootcounter support on blackfin based boards.
 +              CONFIG_SOC_DA8XX
 +              enable special bootcounter support on da850 based boards.
 +              CONFIG_BOOTCOUNT_RAM
 +              enable support for the bootcounter in RAM
 +              CONFIG_BOOTCOUNT_I2C
 +              enable support for the bootcounter on an i2c (like RTC) device.
 +                      CONFIG_SYS_I2C_RTC_ADDR = i2c chip address
 +                      CONFIG_SYS_BOOTCOUNT_ADDR = i2c addr which is used for
 +                                                  the bootcounter.
 +                      CONFIG_BOOTCOUNT_ALEN = address len
  
  - Show boot progress:
                CONFIG_SHOW_BOOT_PROGRESS
@@@ -3414,19 -2863,6 +3425,19 @@@ FIT uImage format
   -150 common/cmd_nand.c       Incorrect FIT image format
    151 common/cmd_nand.c       FIT image format OK
  
 +- legacy image format:
 +              CONFIG_IMAGE_FORMAT_LEGACY
 +              enables the legacy image format support in U-Boot.
 +
 +              Default:
 +              enabled if CONFIG_FIT_SIGNATURE is not defined.
 +
 +              CONFIG_DISABLE_IMAGE_LEGACY
 +              disable the legacy image format
 +
 +              This define is introduced, as the legacy image format is
 +              enabled per default for backward compatibility.
 +
  - FIT image support:
                CONFIG_FIT
                Enable support for the FIT uImage format.
                using a hash signed and verified using RSA. See
                doc/uImage.FIT/signature.txt for more details.
  
 +              WARNING: When relying on signed FIT images with required
 +              signature check the legacy image format is default
 +              disabled. If a board need legacy image format support
 +              enable this through CONFIG_IMAGE_FORMAT_LEGACY
 +
 +              CONFIG_FIT_DISABLE_SHA256
 +              Supporting SHA256 hashes has quite an impact on binary size.
 +              For constrained systems sha256 hash support can be disabled
 +              with this option.
 +
  - Standalone program support:
                CONFIG_STANDALONE_LOAD_ADDR
  
                Adds the MTD partitioning infrastructure from the Linux
                kernel. Needed for UBI support.
  
 +              CONFIG_MTD_NAND_VERIFY_WRITE
 +              verify if the written data is correct reread.
 +
  - UBI support
                CONFIG_CMD_UBI
  
                Make the verbose messages from UBI stop printing.  This leaves
                warnings and errors enabled.
  
 +
 +              CONFIG_MTD_UBI_WL_THRESHOLD
 +              This parameter defines the maximum difference between the highest
 +              erase counter value and the lowest erase counter value of eraseblocks
 +              of UBI devices. When this threshold is exceeded, UBI starts performing
 +              wear leveling by means of moving data from eraseblock with low erase
 +              counter to eraseblocks with high erase counter.
 +
 +              The default value should be OK for SLC NAND flashes, NOR flashes and
 +              other flashes which have eraseblock life-cycle 100000 or more.
 +              However, in case of MLC NAND flashes which typically have eraseblock
 +              life-cycle less than 10000, the threshold should be lessened (e.g.,
 +              to 128 or 256, although it does not have to be power of 2).
 +
 +              default: 4096
 +
 +              CONFIG_MTD_UBI_BEB_LIMIT
 +              This option specifies the maximum bad physical eraseblocks UBI
 +              expects on the MTD device (per 1024 eraseblocks). If the
 +              underlying flash does not admit of bad eraseblocks (e.g. NOR
 +              flash), this value is ignored.
 +
 +              NAND datasheets often specify the minimum and maximum NVM
 +              (Number of Valid Blocks) for the flashes' endurance lifetime.
 +              The maximum expected bad eraseblocks per 1024 eraseblocks
 +              then can be calculated as "1024 * (1 - MinNVB / MaxNVB)",
 +              which gives 20 for most NANDs (MaxNVB is basically the total
 +              count of eraseblocks on the chip).
 +
 +              To put it differently, if this value is 20, UBI will try to
 +              reserve about 1.9% of physical eraseblocks for bad blocks
 +              handling. And that will be 1.9% of eraseblocks on the entire
 +              NAND chip, not just the MTD partition UBI attaches. This means
 +              that if you have, say, a NAND flash chip admits maximum 40 bad
 +              eraseblocks, and it is split on two MTD partitions of the same
 +              size, UBI will reserve 40 eraseblocks when attaching a
 +              partition.
 +
 +              default: 20
 +
 +              CONFIG_MTD_UBI_FASTMAP
 +              Fastmap is a mechanism which allows attaching an UBI device
 +              in nearly constant time. Instead of scanning the whole MTD device it
 +              only has to locate a checkpoint (called fastmap) on the device.
 +              The on-flash fastmap contains all information needed to attach
 +              the device. Using fastmap makes only sense on large devices where
 +              attaching by scanning takes long. UBI will not automatically install
 +              a fastmap on old images, but you can set the UBI parameter
 +              CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT to 1 if you want so. Please note
 +              that fastmap-enabled images are still usable with UBI implementations
 +              without fastmap support. On typical flash devices the whole fastmap
 +              fits into one PEB. UBI will reserve PEBs to hold two fastmaps.
 +
 +              CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT
 +              Set this parameter to enable fastmap automatically on images
 +              without a fastmap.
 +              default: 0
 +
  - UBIFS support
                CONFIG_CMD_UBIFS
  
                supports MMC, NAND and YMODEM loading of U-Boot and NAND
                NAND loading of the Linux Kernel.
  
 +              CONFIG_SPL_OS_BOOT
 +              Enable booting directly to an OS from SPL.
 +              See also: doc/README.falcon
 +
                CONFIG_SPL_DISPLAY_PRINT
                For ARM, enable an optional function to print more information
                about the running system.
  
                CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
                CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS,
 -              CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION
 -              Address, size and partition on the MMC to load U-Boot from
 +              Address and partition on the MMC to load U-Boot from
                when the MMC is being used in raw mode.
  
 +              CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
 +              Partition on the MMC to load U-Boot from when the MMC is being
 +              used in raw mode
 +
                CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR
                Sector to load kernel uImage from when MMC is being
                used in raw mode (for Falcon mode)
                parameters from when MMC is being used in raw mode
                (for falcon mode)
  
 +              CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
 +              Partition on the MMC to load U-Boot from when the MMC is being
 +              used in fs mode
 +
                CONFIG_SPL_FAT_SUPPORT
                Support for fs/fat/libfat.o in SPL binary
  
 -              CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
 -              Filename to read to load U-Boot when reading from FAT
 +              CONFIG_SPL_EXT_SUPPORT
 +              Support for EXT filesystem in SPL binary
  
 -              CONFIG_SPL_FAT_LOAD_KERNEL_NAME
 +              CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
 +              Filename to read to load U-Boot when reading from filesystem
 +
 +              CONFIG_SPL_FS_LOAD_KERNEL_NAME
                Filename to read to load kernel uImage when reading
 -              from FAT (for Falcon mode)
 +              from filesystem (for Falcon mode)
  
 -              CONFIG_SPL_FAT_LOAD_ARGS_NAME
 +              CONFIG_SPL_FS_LOAD_ARGS_NAME
                Filename to read to load kernel argument parameters
 -              when reading from FAT (for Falcon mode)
 +              when reading from filesystem (for Falcon mode)
  
                CONFIG_SPL_MPC83XX_WAIT_FOR_NAND
                Set this for NAND SPL on PPC mpc83xx targets, so that
                continuing (the hardware starts execution after just
                loading the first page rather than the full 4K).
  
 +              CONFIG_SPL_SKIP_RELOCATE
 +              Avoid SPL relocation
 +
                CONFIG_SPL_NAND_BASE
                Include nand_base.c in the SPL.  Requires
                CONFIG_SPL_NAND_DRIVERS.
                Support for NAND boot using simple NAND drivers that
                expose the cmd_ctrl() interface.
  
 +              CONFIG_SPL_MTD_SUPPORT
 +              Support for the MTD subsystem within SPL.  Useful for
 +              environment on NAND support within SPL.
 +
 +              CONFIG_SPL_NAND_RAW_ONLY
 +              Support to boot only raw u-boot.bin images. Use this only
 +              if you need to save space.
 +
 +              CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT
 +              Set for the SPL on PPC mpc8xxx targets, support for
 +              drivers/ddr/fsl/libddr.o in SPL binary.
 +
 +              CONFIG_SPL_COMMON_INIT_DDR
 +              Set for common ddr init with serial presence detect in
 +              SPL binary.
 +
                CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
                CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
                CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS,
                Defines the size and behavior of the NAND that SPL uses
                to read U-Boot
  
 +              CONFIG_SPL_NAND_BOOT
 +              Add support NAND boot
 +
                CONFIG_SYS_NAND_U_BOOT_OFFS
                Location in NAND to read U-Boot from
  
  
                CONFIG_SYS_NAND_HW_ECC_OOBFIRST
                Define this if you need to first read the OOB and then the
 -              data. This is used for example on davinci plattforms.
 +              data. This is used, for example, on davinci platforms.
  
                CONFIG_SPL_OMAP3_ID_NAND
                Support for an OMAP3-specific set of functions to return the
                option to re-enable it. This will affect the output of the
                bootm command when booting a FIT image.
  
 +- TPL framework
 +              CONFIG_TPL
 +              Enable building of TPL globally.
 +
 +              CONFIG_TPL_PAD_TO
 +              Image offset to which the TPL should be padded before appending
 +              the TPL payload. By default, this is defined as
 +              CONFIG_SPL_MAX_SIZE, or 0 if CONFIG_SPL_MAX_SIZE is undefined.
 +              CONFIG_SPL_PAD_TO must be either 0, meaning to append the SPL
 +              payload without any padding, or >= CONFIG_SPL_MAX_SIZE.
 +
  Modem Support:
  --------------
  
@@@ -3890,9 -3208,6 +3901,9 @@@ typically in board_init_f() and board_i
  Configuration Settings:
  -----------------------
  
 +- CONFIG_SYS_SUPPORT_64BIT_DATA: Defined automatically if compiled as 64-bit.
 +              Optionally it can be defined to support 64-bit memory commands.
 +
  - CONFIG_SYS_LONGHELP: Defined when you want long help messages included;
                undefine this when you're short of memory.
  
  - CONFIG_SYS_MALLOC_LEN:
                Size of DRAM reserved for malloc() use.
  
 +- CONFIG_SYS_MALLOC_F_LEN
 +              Size of the malloc() pool for use before relocation. If
 +              this is defined, then a very simple malloc() implementation
 +              will become available before relocation. The address is just
 +              below the global data, and the stack is moved down to make
 +              space.
 +
 +              This feature allocates regions with increasing addresses
 +              within the region. calloc() is supported, but realloc()
 +              is not available. free() is supported but does nothing.
 +              The memory will be freed (or in fact just forgotten) when
 +              U-Boot relocates itself.
 +
 +              Pre-relocation malloc() is only supported on ARM and sandbox
 +              at present but is fairly easy to enable for other archs.
 +
 +- CONFIG_SYS_MALLOC_SIMPLE
 +              Provides a simple and small malloc() and calloc() for those
 +              boards which do not use the full malloc in SPL (which is
 +              enabled with CONFIG_SYS_SPL_MALLOC_START).
 +
 +- CONFIG_SYS_NONCACHED_MEMORY:
 +              Size of non-cached memory area. This area of memory will be
 +              typically located right below the malloc() area and mapped
 +              uncached in the MMU. This is useful for drivers that would
 +              otherwise require a lot of explicit cache maintenance. For
 +              some drivers it's also impossible to properly maintain the
 +              cache. For example if the regions that need to be flushed
 +              are not a multiple of the cache-line size, *and* padding
 +              cannot be allocated between the regions to align them (i.e.
 +              if the HW requires a contiguous array of regions, and the
 +              size of each region is not cache-aligned), then a flush of
 +              one region may result in overwriting data that hardware has
 +              written to another region in the same cache-line. This can
 +              happen for example in network drivers where descriptors for
 +              buffers are typically smaller than the CPU cache-line (e.g.
 +              16 bytes vs. 32 or 64 bytes).
 +
 +              Non-cached memory is only supported on 32-bit ARM at present.
 +
  - CONFIG_SYS_BOOTM_LEN:
                Normally compressed uImages are limited to an
                uncompressed size of 8 MBytes. If this is not enough,
                the Linux kernel; all data that must be processed by
                the Linux kernel (bd_info, boot arguments, FDT blob if
                used) must be put below this limit, unless "bootm_low"
 -              enviroment variable is defined and non-zero. In such case
 +              environment variable is defined and non-zero. In such case
                all data for the Linux kernel must be between "bootm_low"
                and "bootm_low" + CONFIG_SYS_BOOTMAPSZ.  The environment
                variable "bootm_mapsize" will override the value of
  
  - CONFIG_ENV_FLAGS_LIST_DEFAULT
  - CONFIG_ENV_FLAGS_LIST_STATIC
 -      Enable validation of the values given to enviroment variables when
 +      Enable validation of the values given to environment variables when
        calling env set.  Variables can be restricted to only decimal,
        hexadecimal, or boolean.  If CONFIG_CMD_NET is also defined,
        the variables can also be restricted to IP address or MAC address.
  
        The format of the list is:
                type_attribute = [s|d|x|b|i|m]
 -              access_atribute = [a|r|o|c]
 -              attributes = type_attribute[access_atribute]
 +              access_attribute = [a|r|o|c]
 +              attributes = type_attribute[access_attribute]
                entry = variable_name[:attributes]
                list = entry[,list]
  
  
        - CONFIG_ENV_FLAGS_LIST_DEFAULT
                Define this to a list (string) to define the ".flags"
 -              envirnoment variable in the default or embedded environment.
 +              environment variable in the default or embedded environment.
  
        - CONFIG_ENV_FLAGS_LIST_STATIC
                Define this to a list (string) to define validation that
        its config.mk file). If you find problems enabling this option on
        your board please report the problem and send patches!
  
 -- CONFIG_SYS_SYM_OFFSETS
 -      This is set by architectures that use offsets for link symbols
 -      instead of absolute values. So bss_start is obtained using an
 -      offset _bss_start_ofs from CONFIG_SYS_TEXT_BASE, rather than
 -      directly. You should not need to touch this setting.
 -
  - CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC (OMAP only)
        This is set by OMAP boards for the max time that reset should
        be asserted. See doc/README.omap-reset-time for details on how
 -      the value can be calulated on a given board.
 +      the value can be calculated on a given board.
 +
 +- CONFIG_USE_STDINT
 +      If stdint.h is available with your toolchain you can define this
 +      option to enable it. You can provide option 'USE_STDINT=1' when
 +      building U-Boot to enable this.
  
  The following definitions that deal with the placement and management
  of environment data (variable area); in general, we support the
@@@ -4309,7 -3585,7 +4320,7 @@@ accordingly
          provision.
  
  BE CAREFUL! The first access to the environment happens quite early
 -in U-Boot initalization (when we try to get the setting of for the
 +in U-Boot initialization (when we try to get the setting of for the
  console baudrate). You *MUST* have mapped your NVRAM area then, or
  U-Boot will hang.
  
@@@ -4388,43 -3664,6 +4399,43 @@@ to save the current settings
          environment area within the total memory of your DataFlash placed
          at the specified address.
  
 +- CONFIG_ENV_IS_IN_SPI_FLASH:
 +
 +      Define this if you have a SPI Flash memory device which you
 +      want to use for the environment.
 +
 +      - CONFIG_ENV_OFFSET:
 +      - CONFIG_ENV_SIZE:
 +
 +        These two #defines specify the offset and size of the
 +        environment area within the SPI Flash. CONFIG_ENV_OFFSET must be
 +        aligned to an erase sector boundary.
 +
 +      - CONFIG_ENV_SECT_SIZE:
 +
 +        Define the SPI flash's sector size.
 +
 +      - CONFIG_ENV_OFFSET_REDUND (optional):
 +
 +        This setting describes a second storage area of CONFIG_ENV_SIZE
 +        size used to hold a redundant copy of the environment data, so
 +        that there is a valid backup copy in case there is a power failure
 +        during a "saveenv" operation. CONFIG_ENV_OFFSET_RENDUND must be
 +        aligned to an erase sector boundary.
 +
 +      - CONFIG_ENV_SPI_BUS (optional):
 +      - CONFIG_ENV_SPI_CS (optional):
 +
 +        Define the SPI bus and chip select. If not defined they will be 0.
 +
 +      - CONFIG_ENV_SPI_MAX_HZ (optional):
 +
 +        Define the SPI max work clock. If not defined then use 1MHz.
 +
 +      - CONFIG_ENV_SPI_MODE (optional):
 +
 +        Define the SPI work mode. If not defined then use SPI_MODE_3.
 +
  - CONFIG_ENV_IS_IN_REMOTE:
  
        Define this if you have a remote memory space which you
@@@ -4512,37 -3751,6 +4523,37 @@@ but it can not erase, write this NOR fl
          You will probably want to define these to avoid a really noisy system
          when storing the env in UBI.
  
 +- CONFIG_ENV_IS_IN_FAT:
 +       Define this if you want to use the FAT file system for the environment.
 +
 +       - FAT_ENV_INTERFACE:
 +
 +         Define this to a string that is the name of the block device.
 +
 +       - FAT_ENV_DEV_AND_PART:
 +
 +         Define this to a string to specify the partition of the device. It can
 +         be as following:
 +
 +           "D:P", "D:0", "D", "D:" or "D:auto" (D, P are integers. And P >= 1)
 +               - "D:P": device D partition P. Error occurs if device D has no
 +                        partition table.
 +               - "D:0": device D.
 +               - "D" or "D:": device D partition 1 if device D has partition
 +                              table, or the whole device D if has no partition
 +                              table.
 +               - "D:auto": first partition in device D with bootable flag set.
 +                           If none, first valid partition in device D. If no
 +                           partition table then means device D.
 +
 +       - FAT_ENV_FILE:
 +
 +         It's a string of the FAT file name. This file use to store the
 +         environment.
 +
 +       - CONFIG_FAT_WRITE:
 +         This should be defined. Otherwise it cannot save the environment file.
 +
  - CONFIG_ENV_IS_IN_MMC:
  
        Define this if you have an MMC device which you want to use for the
@@@ -4646,11 -3854,6 +4657,11 @@@ use the "saveenv" command to store a va
                later, once stdio is running and output goes to the LCD, if
                present.
  
 +- CONFIG_BOARD_SIZE_LIMIT:
 +              Maximum size of the U-Boot image. When defined, the
 +              build system checks that the actual size does not
 +              exceed it.
 +
  Low Level (hardware related) configuration options:
  ---------------------------------------------------
  
                if CONFIG_SYS_FDC_HW_INIT is defined, then the function
                fdc_hw_init() is called at the beginning of the FDC
                setup. fdc_hw_init() must be provided by the board
 -              source code. It is used to make hardware dependant
 +              source code. It is used to make hardware-dependent
                initializations.
  
  - CONFIG_IDE_AHB:
                When software is doing ATA command and data transfer to
                IDE devices through IDE-AHB controller, some additional
                registers accessing to these kind of IDE-AHB controller
 -              is requierd.
 +              is required.
  
  - CONFIG_SYS_IMMR:    Physical address of the Internal Memory.
                DO NOT CHANGE unless you know exactly what you're
                required.
  
  - CONFIG_PCI_ENUM_ONLY
 -              Only scan through and get the devices on the busses.
 +              Only scan through and get the devices on the buses.
                Don't do any setup work, presumably because someone or
                something has already done it, and we don't need to do it
                a second time.  Useful for platforms that are pre-booted
                that is executed before the actual U-Boot. E.g. when
                compiling a NAND SPL.
  
 +- CONFIG_TPL_BUILD
 +              Modifies the behaviour of start.S  when compiling a loader
 +              that is executed after the SPL and before the actual U-Boot.
 +              It is loaded by the SPL.
 +
  - CONFIG_SYS_MPC85XX_NO_RESETVEC
                Only for 85xx systems. If this variable is specified, the section
                .resetvec is not kept and the section .bootpg is placed in the
  
                NOTE : currently only supported on AM335x platforms.
  
 +- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
 +              Enables the RTC32K OSC on AM33xx based plattforms
 +
 +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
 +              Option to disable subpage write in NAND driver
 +              driver that uses this:
 +              drivers/mtd/nand/davinci_nand.c
 +
  Freescale QE/FMAN Firmware Support:
  -----------------------------------
  
@@@ -5028,13 -4218,8 +5039,13 @@@ This firmware often needs to be loaded 
  are used to identify the storage device (NOR flash, SPI, etc) and the address
  within that device.
  
 -- CONFIG_SYS_QE_FMAN_FW_ADDR
 -      The address in the storage device where the firmware is located.  The
 +- CONFIG_SYS_FMAN_FW_ADDR
 +      The address in the storage device where the FMAN microcode is located.  The
 +      meaning of this address depends on which CONFIG_SYS_QE_FW_IN_xxx macro
 +      is also specified.
 +
 +- CONFIG_SYS_QE_FW_ADDR
 +      The address in the storage device where the QE microcode is located.  The
        meaning of this address depends on which CONFIG_SYS_QE_FW_IN_xxx macro
        is also specified.
  
        window->master inbound window->master LAW->the ucode address in
        master's memory space.
  
 +Freescale Layerscape Management Complex Firmware Support:
 +---------------------------------------------------------
 +The Freescale Layerscape Management Complex (MC) supports the loading of
 +"firmware".
 +This firmware often needs to be loaded during U-Boot booting, so macros
 +are used to identify the storage device (NOR flash, SPI, etc) and the address
 +within that device.
 +
 +- CONFIG_FSL_MC_ENET
 +      Enable the MC driver for Layerscape SoCs.
 +
 +- CONFIG_SYS_LS_MC_FW_ADDR
 +      The address in the storage device where the firmware is located.  The
 +      meaning of this address depends on which CONFIG_SYS_LS_MC_FW_IN_xxx macro
 +      is also specified.
 +
 +- CONFIG_SYS_LS_MC_FW_LENGTH
 +      The maximum possible size of the firmware.  The firmware binary format
 +      has a field that specifies the actual size of the firmware, but it
 +      might not be possible to read any part of the firmware unless some
 +      local storage is allocated to hold the entire firmware first.
 +
 +- CONFIG_SYS_LS_MC_FW_IN_NOR
 +      Specifies that MC firmware is located in NOR flash, mapped as
 +      normal addressable memory via the LBC. CONFIG_SYS_LS_MC_FW_ADDR is the
 +      virtual address in NOR flash.
 +
  Building the Software:
  ======================
  
@@@ -5128,9 -4286,9 +5139,9 @@@ U-Boot is intended to be simple to buil
  sources you must configure U-Boot for one specific board type. This
  is done by typing:
  
 -      make NAME_config
 +      make NAME_defconfig
  
 -where "NAME_config" is the name of one of the existing configu-
 +where "NAME_defconfig" is the name of one of the existing configu-
  rations; see boards.cfg for supported names.
  
  Note: for some board special configuration names may exist; check if
        or with LCD support. You can select such additional "features"
        when choosing the configuration, i. e.
  
 -      make TQM823L_config
 +      make TQM823L_defconfig
        - will configure for a plain TQM823L, i. e. no LCD support
  
 -      make TQM823L_LCD_config
 +      make TQM823L_LCD_defconfig
        - will configure for a TQM823L with U-Boot console on LCD
  
        etc.
@@@ -5162,17 -4320,17 +5173,17 @@@ this behavior and build U-Boot to some 
  1. Add O= to the make command line invocations:
  
        make O=/tmp/build distclean
 -      make O=/tmp/build NAME_config
 +      make O=/tmp/build NAME_defconfig
        make O=/tmp/build all
  
 -2. Set environment variable BUILD_DIR to point to the desired location:
 +2. Set environment variable KBUILD_OUTPUT to point to the desired location:
  
 -      export BUILD_DIR=/tmp/build
 +      export KBUILD_OUTPUT=/tmp/build
        make distclean
 -      make NAME_config
 +      make NAME_defconfig
        make all
  
 -Note that the command line "O=" setting overrides the BUILD_DIR environment
 +Note that the command line "O=" setting overrides the KBUILD_OUTPUT environment
  variable.
  
  
@@@ -5195,7 -4353,7 +5206,7 @@@ steps
      your board
  3.  If you're porting U-Boot to a new CPU, then also create a new
      directory to hold your CPU specific code. Add any files you need.
 -4.  Run "make <board>_config" with your new name.
 +4.  Run "make <board>_defconfig" with your new name.
  5.  Type "make", and you should get a working "u-boot.srec" file
      to be installed on your target system.
  6.  Debug and solve any problems that might arise.
@@@ -5468,12 -4626,6 +5479,12 @@@ List of environment variables (most lik
  
    npe_ucode   - set load address for the NPE microcode
  
 +  silent_linux  - If set then Linux will be told to boot silently, by
 +                changing the console to be empty. If "yes" it will be
 +                made silent. If "no" it will not be made silent. If
 +                unset, then it will be made silent if the U-Boot console
 +                is silent.
 +
    tftpsrcport - If this is set, the value is used for TFTP's
                  UDP source port.
  
@@@ -5555,7 -4707,7 +5566,7 @@@ Callback functions for environment vari
  ---------------------------------------------
  
  For some environment variables, the behavior of u-boot needs to change
 -when their values are changed.  This functionailty allows functions to
 +when their values are changed.  This functionality allows functions to
  be associated with arbitrary variables.  On creation, overwrite, or
  deletion, the callback will provide the opportunity for some side
  effect to happen or for the change to be rejected.
@@@ -5578,7 -4730,7 +5589,7 @@@ Callbacks can also be associated by def
  with the same list format above.  Any association in ".callbacks" will
  override any association in the static list. You can define
  CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the
 -".callbacks" envirnoment variable in the default or embedded environment.
 +".callbacks" environment variable in the default or embedded environment.
  
  
  Command Line Parsing:
@@@ -5750,11 -4902,6 +5761,11 @@@ Information structure as we define in i
  and make sure that your definition of IMAP_ADDR uses the same value
  as your U-Boot configuration in CONFIG_SYS_IMMR.
  
 +Note that U-Boot now has a driver model, a unified model for drivers.
 +If you are adding a new driver, plumb it into driver model. If there
 +is no uclass available, you are encouraged to create one. See
 +doc/driver-model.
 +
  
  Configuring the Linux kernel:
  -----------------------------
@@@ -5775,7 -4922,7 +5786,7 @@@ which was introduced for our predecesso
  
  Example:
  
 -      make TQM850L_config
 +      make TQM850L_defconfig
        make oldconfig
        make dep
        make uImage
@@@ -5895,15 -5042,6 +5906,15 @@@ when your kernel is intended to use an 
        Load Address: 0x00000000
        Entry Point:  0x00000000
  
 +The "dumpimage" is a tool to disassemble images built by mkimage. Its "-i"
 +option performs the converse operation of the mkimage's second form (the "-d"
 +option). Given an image built by mkimage, the dumpimage extracts a "data file"
 +from the image:
 +
 +      tools/dumpimage -i image -p position data_file
 +        -i ==> extract from the 'image' a specific 'data_file', \
 +         indexed by 'position'
 +
  
  Installing a Linux Image:
  -------------------------
@@@ -6343,7 -5481,7 +6354,7 @@@ code for the initialization procedures
  * Initialized global data (data segment) is read-only. Do not attempt
    to write it.
  
 -* Do not use any uninitialized global data (or implicitely initialized
 +* Do not use any uninitialized global data (or implicitly initialized
    as zero data - BSS segment) at all - this is undefined, initiali-
    zation is performed later (when relocating to RAM).
  
    that.
  
  Having only the stack as writable memory limits means we cannot use
 -normal global data to share information beween the code. But it
 +normal global data to share information between the code. But it
  turned out that the implementation of U-Boot can be greatly
  simplified by making a global data structure (gd_t) available to all
  functions. We could pass a pointer to this data as argument to _all_
@@@ -6395,17 -5533,15 +6406,17 @@@ On ARM, the following registers are use
  
        R0:     function argument word/integer result
        R1-R3:  function argument word
 -      R9:     GOT pointer
 -      R10:    stack limit (used only if stack checking if enabled)
 +      R9:     platform specific
 +      R10:    stack limit (used only if stack checking is enabled)
        R11:    argument (frame) pointer
        R12:    temporary workspace
        R13:    stack pointer
        R14:    link register
        R15:    program counter
  
 -    ==> U-Boot will use R8 to hold a pointer to the global data
 +    ==> U-Boot will use R9 to hold a pointer to the global data
 +
 +    Note: on ARM, only R_ARM_RELATIVE relocations are supported.
  
  On Nios II, the ABI is documented here:
        http://www.altera.com/literature/hb/nios2/n2cpu_nii51016.pdf
@@@ -6482,7 -5618,7 +6493,7 @@@ System Initialization
  
  In the reset configuration, U-Boot starts at the reset entry point
  (on most PowerPC systems at address 0x00000100). Because of the reset
 -configuration for CS0# this is a mirror of the onboard Flash memory.
 +configuration for CS0# this is a mirror of the on board Flash memory.
  To be able to re-map memory U-Boot then jumps to its link address.
  To be able to implement the initialization code in C, a (small!)
  initial stack is set up in the internal Dual Ported RAM (in case CPUs
@@@ -6598,7 -5734,7 +6609,7 @@@ coding style; see the file "Documentati
  
  Source files originating from a different project (for example the
  MTD subsystem) are generally exempt from these guidelines and are not
 -reformated to ease subsequent migration to newer versions of those
 +reformatted to ease subsequent migration to newer versions of those
  sources.
  
  Please note that U-Boot is implemented in C (and to some small parts in
@@@ -6642,8 -5778,8 +6653,8 @@@ it
  
  * For major contributions, your entry to the CREDITS file
  
 -* When you add support for a new board, don't forget to add this
 -  board to the MAINTAINERS file, too.
 +* When you add support for a new board, don't forget to add a
 +  maintainer e-mail address to the boards.cfg file, too.
  
  * If your patch adds new configuration options, don't forget to
    document these in the README file.
diff --combined arch/arm/Kconfig
index 5eb1d03cfaafbdb8faf75c01cb5cc5839c0102a1,0000000000000000000000000000000000000000..682f882fc0610f89c57b97f38221aa3478e0056f
mode 100644,000000..100644
--- /dev/null
@@@ -1,989 -1,0 +1,1016 @@@
 +menu "ARM architecture"
 +      depends on ARM
 +
 +config SYS_ARCH
 +      default "arm"
 +
 +config ARM64
 +      bool
 +
 +config HAS_VBAR
 +        bool
 +
 +config CPU_ARM720T
 +        bool
 +
 +config CPU_ARM920T
 +        bool
 +
 +config CPU_ARM926EJS
 +        bool
 +
 +config CPU_ARM946ES
 +        bool
 +
 +config CPU_ARM1136
 +        bool
 +
 +config CPU_ARM1176
 +        bool
 +        select HAS_VBAR
 +
 +config CPU_V7
 +        bool
 +        select HAS_VBAR
 +
 +config CPU_PXA
 +        bool
 +
 +config CPU_SA1100
 +        bool
 +
 +config SYS_CPU
 +        default "arm720t" if CPU_ARM720T
 +        default "arm920t" if CPU_ARM920T
 +        default "arm926ejs" if CPU_ARM926EJS
 +        default "arm946es" if CPU_ARM946ES
 +        default "arm1136" if CPU_ARM1136
 +        default "arm1176" if CPU_ARM1176
 +        default "armv7" if CPU_V7
 +        default "pxa" if CPU_PXA
 +        default "sa1100" if CPU_SA1100
 +      default "armv8" if ARM64
 +
 +choice
 +      prompt "Target select"
 +
 +config TARGET_INTEGRATORAP_CM720T
 +      bool "Support integratorap_cm720t"
 +      select CPU_ARM720T
 +
 +config TARGET_INTEGRATORAP_CM920T
 +      bool "Support integratorap_cm920t"
 +      select CPU_ARM920T
 +
 +config TARGET_INTEGRATORCP_CM920T
 +      bool "Support integratorcp_cm920t"
 +      select CPU_ARM920T
 +
 +config TARGET_A320EVB
 +      bool "Support a320evb"
 +      select CPU_ARM920T
 +
 +config TARGET_AT91RM9200EK
 +      bool "Support at91rm9200ek"
 +      select CPU_ARM920T
 +
 +config TARGET_EB_CPUX9K2
 +      bool "Support eb_cpux9k2"
 +      select CPU_ARM920T
 +
 +config TARGET_CPUAT91
 +      bool "Support cpuat91"
 +      select CPU_ARM920T
 +
 +config TARGET_EDB93XX
 +      bool "Support edb93xx"
 +      select CPU_ARM920T
 +
 +config TARGET_SCB9328
 +      bool "Support scb9328"
 +      select CPU_ARM920T
 +
 +config TARGET_CM4008
 +      bool "Support cm4008"
 +      select CPU_ARM920T
 +
 +config TARGET_CM41XX
 +      bool "Support cm41xx"
 +      select CPU_ARM920T
 +
 +config TARGET_VCMA9
 +      bool "Support VCMA9"
 +      select CPU_ARM920T
 +
 +config TARGET_SMDK2410
 +      bool "Support smdk2410"
 +      select CPU_ARM920T
 +
 +config TARGET_INTEGRATORAP_CM926EJS
 +      bool "Support integratorap_cm926ejs"
 +      select CPU_ARM926EJS
 +
 +config TARGET_INTEGRATORCP_CM926EJS
 +      bool "Support integratorcp_cm926ejs"
 +      select CPU_ARM926EJS
 +
 +config TARGET_ASPENITE
 +      bool "Support aspenite"
 +      select CPU_ARM926EJS
 +
 +config TARGET_GPLUGD
 +      bool "Support gplugd"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AFEB9260
 +      bool "Support afeb9260"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9260EK
 +      bool "Support at91sam9260ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9261EK
 +      bool "Support at91sam9261ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9263EK
 +      bool "Support at91sam9263ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9M10G45EK
 +      bool "Support at91sam9m10g45ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9N12EK
 +      bool "Support at91sam9n12ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9RLEK
 +      bool "Support at91sam9rlek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_AT91SAM9X5EK
 +      bool "Support at91sam9x5ek"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SNAPPER9260
 +      bool "Support snapper9260"
 +      select CPU_ARM926EJS
 +
 +config TARGET_VL_MA2SC
 +      bool "Support vl_ma2sc"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SBC35_A9G20
 +      bool "Support sbc35_a9g20"
 +      select CPU_ARM926EJS
 +
 +config TARGET_TNY_A9260
 +      bool "Support tny_a9260"
 +      select CPU_ARM926EJS
 +
 +config TARGET_USB_A9263
 +      bool "Support usb_a9263"
 +      select CPU_ARM926EJS
 +
 +config TARGET_ETHERNUT5
 +      bool "Support ethernut5"
 +      select CPU_ARM926EJS
 +
 +config TARGET_MEESC
 +      bool "Support meesc"
 +      select CPU_ARM926EJS
 +
 +config TARGET_OTC570
 +      bool "Support otc570"
 +      select CPU_ARM926EJS
 +
 +config TARGET_CPU9260
 +      bool "Support cpu9260"
 +      select CPU_ARM926EJS
 +
 +config TARGET_PM9261
 +      bool "Support pm9261"
 +      select CPU_ARM926EJS
 +
 +config TARGET_PM9263
 +      bool "Support pm9263"
 +      select CPU_ARM926EJS
 +
 +config TARGET_PM9G45
 +      bool "Support pm9g45"
 +      select CPU_ARM926EJS
 +
 +config TARGET_CORVUS
 +      select SUPPORT_SPL
 +      bool "Support corvus"
 +      select CPU_ARM926EJS
 +
 +config TARGET_TAURUS
 +      select SUPPORT_SPL
 +      bool "Support taurus"
 +      select CPU_ARM926EJS
 +
 +config TARGET_STAMP9G20
 +      bool "Support stamp9g20"
 +      select CPU_ARM926EJS
 +
 +config ARCH_DAVINCI
 +      bool "TI DaVinci"
 +      select CPU_ARM926EJS
 +      help
 +        Support for TI's DaVinci platform.
 +
 +config KIRKWOOD
 +      bool "Marvell Kirkwood"
 +      select CPU_ARM926EJS
 +
 +config TARGET_DB_MV784MP_GP
 +      bool "Support db-mv784mp-gp"
 +      select CPU_V7
 +
 +config TARGET_MAXBCM
 +      bool "Support maxbcm"
 +      select CPU_V7
 +
 +config TARGET_DEVKIT3250
 +      bool "Support devkit3250"
 +      select CPU_ARM926EJS
 +
 +config TARGET_JADECPU
 +      bool "Support jadecpu"
 +      select CPU_ARM926EJS
 +
 +config TARGET_MX25PDK
 +      bool "Support mx25pdk"
 +      select CPU_ARM926EJS
 +
 +config TARGET_TX25
 +      bool "Support tx25"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
++config TARGET_TX28
++      bool "Support tx28"
++      select CPU_ARM926EJS
++      select SUPPORT_SPL
++
++config TARGET_TX48
++      bool "Support tx48"
++      select CPU_V7
++      select SUPPORT_SPL
++
++config TARGET_TX51
++      bool "Support tx51"
++      select CPU_V7
++
++config TARGET_TX53
++      bool "Support tx53"
++      select CPU_V7
++
++config TARGET_TX6
++      bool "Support tx6"
++      select CPU_V7
++
 +config TARGET_ZMX25
 +      bool "Support zmx25"
 +      select CPU_ARM926EJS
 +
 +config TARGET_APF27
 +      bool "Support apf27"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_IMX27LITE
 +      bool "Support imx27lite"
 +      select CPU_ARM926EJS
 +
 +config TARGET_MAGNESIUM
 +      bool "Support magnesium"
 +      select CPU_ARM926EJS
 +
 +config TARGET_APX4DEVKIT
 +      bool "Support apx4devkit"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_XFI3
 +      bool "Support xfi3"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_M28EVK
 +      bool "Support m28evk"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_MX23EVK
 +      bool "Support mx23evk"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_MX28EVK
 +      bool "Support mx28evk"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_MX23_OLINUXINO
 +      bool "Support mx23_olinuxino"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_BG0900
 +      bool "Support bg0900"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_SANSA_FUZE_PLUS
 +      bool "Support sansa_fuze_plus"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config TARGET_SC_SPS_1
 +      bool "Support sc_sps_1"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config ARCH_NOMADIK
 +      bool "ST-Ericsson Nomadik"
 +      select CPU_ARM926EJS
 +
 +config ORION5X
 +      bool "Marvell Orion"
 +      select CPU_ARM926EJS
 +
 +config TARGET_DKB
 +      bool "Support dkb"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SPEAR300
 +      bool "Support spear300"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SPEAR310
 +      bool "Support spear310"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SPEAR320
 +      bool "Support spear320"
 +      select CPU_ARM926EJS
 +
 +config TARGET_SPEAR600
 +      bool "Support spear600"
 +      select CPU_ARM926EJS
 +
 +config TARGET_STV0991
 +      bool "Support stv0991"
 +      select CPU_V7
 +
 +config TARGET_X600
 +      bool "Support x600"
 +      select CPU_ARM926EJS
 +      select SUPPORT_SPL
 +
 +config ARCH_VERSATILE
 +      bool "ARM Ltd. Versatile family"
 +      select CPU_ARM926EJS
 +
 +config TARGET_INTEGRATORCP_CM1136
 +      bool "Support integratorcp_cm1136"
 +      select CPU_ARM1136
 +
 +config TARGET_IMX31_PHYCORE
 +      bool "Support imx31_phycore"
 +      select CPU_ARM1136
 +
 +config TARGET_QONG
 +      bool "Support qong"
 +      select CPU_ARM1136
 +
 +config TARGET_MX31ADS
 +      bool "Support mx31ads"
 +      select CPU_ARM1136
 +
 +config TARGET_MX31PDK
 +      bool "Support mx31pdk"
 +      select CPU_ARM1136
 +      select SUPPORT_SPL
 +
 +config TARGET_TT01
 +      bool "Support tt01"
 +      select CPU_ARM1136
 +
 +config TARGET_IMX31_LITEKIT
 +      bool "Support imx31_litekit"
 +      select CPU_ARM1136
 +
 +config TARGET_WOODBURN
 +      bool "Support woodburn"
 +      select CPU_ARM1136
 +
 +config TARGET_WOODBURN_SD
 +      bool "Support woodburn_sd"
 +      select CPU_ARM1136
 +      select SUPPORT_SPL
 +
 +config TARGET_FLEA3
 +      bool "Support flea3"
 +      select CPU_ARM1136
 +
 +config TARGET_MX35PDK
 +      bool "Support mx35pdk"
 +      select CPU_ARM1136
 +
 +config TARGET_RPI
 +      bool "Support rpi"
 +      select CPU_ARM1176
 +
 +config TARGET_TNETV107X_EVM
 +      bool "Support tnetv107x_evm"
 +      select CPU_ARM1176
 +
 +config TARGET_INTEGRATORAP_CM946ES
 +      bool "Support integratorap_cm946es"
 +      select CPU_ARM946ES
 +
 +config TARGET_INTEGRATORCP_CM946ES
 +      bool "Support integratorcp_cm946es"
 +      select CPU_ARM946ES
 +
 +config TARGET_VEXPRESS_CA15_TC2
 +      bool "Support vexpress_ca15_tc2"
 +      select CPU_V7
 +      select CPU_V7_HAS_NONSEC
 +      select CPU_V7_HAS_VIRT
 +
 +config TARGET_VEXPRESS_CA5X2
 +      bool "Support vexpress_ca5x2"
 +      select CPU_V7
 +
 +config TARGET_VEXPRESS_CA9X4
 +      bool "Support vexpress_ca9x4"
 +      select CPU_V7
 +
 +config TARGET_KWB
 +      bool "Support kwb"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_TSERIES
 +      bool "Support tseries"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_CM_T335
 +      bool "Support cm_t335"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_PEPPER
 +      bool "Support pepper"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_AM335X_IGEP0033
 +      bool "Support am335x_igep0033"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_PCM051
 +      bool "Support pcm051"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_DRACO
 +      bool "Support draco"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_DXR2
 +      bool "Support dxr2"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_PXM2
 +      bool "Support pxm2"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_RUT
 +      bool "Support rut"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_PENGWYN
 +      bool "Support pengwyn"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_AM335X_EVM
 +      bool "Support am335x_evm"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_AM43XX_EVM
 +      bool "Support am43xx_evm"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_TI814X_EVM
 +      bool "Support ti814x_evm"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_TI816X_EVM
 +      bool "Support ti816x_evm"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_SAMA5D3_XPLAINED
 +      bool "Support sama5d3_xplained"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_SAMA5D3XEK
 +      bool "Support sama5d3xek"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_SAMA5D4_XPLAINED
 +      bool "Support sama5d4_xplained"
 +      select CPU_V7
 +
 +config TARGET_SAMA5D4EK
 +      bool "Support sama5d4ek"
 +      select CPU_V7
 +
 +config TARGET_BCM28155_AP
 +      bool "Support bcm28155_ap"
 +      select CPU_V7
 +
 +config TARGET_BCMCYGNUS
 +      bool "Support bcmcygnus"
 +      select CPU_V7
 +
 +config TARGET_BCMNSP
 +      bool "Support bcmnsp"
 +      select CPU_V7
 +
 +config ARCH_EXYNOS
 +      bool "Samsung EXYNOS"
 +      select CPU_V7
 +
 +config ARCH_S5PC1XX
 +      bool "Samsung S5PC1XX"
 +      select CPU_V7
 +
 +config ARCH_HIGHBANK
 +      bool "Calxeda Highbank"
 +      select CPU_V7
 +
 +config ARCH_KEYSTONE
 +      bool "TI Keystone"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_M53EVK
 +      bool "Support m53evk"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_IMA3_MX53
 +      bool "Support ima3-mx53"
 +      select CPU_V7
 +
 +config TARGET_MX51EVK
 +      bool "Support mx51evk"
 +      select CPU_V7
 +
 +config TARGET_MX53ARD
 +      bool "Support mx53ard"
 +      select CPU_V7
 +
 +config TARGET_MX53EVK
 +      bool "Support mx53evk"
 +      select CPU_V7
 +
 +config TARGET_MX53LOCO
 +      bool "Support mx53loco"
 +      select CPU_V7
 +
 +config TARGET_MX53SMD
 +      bool "Support mx53smd"
 +      select CPU_V7
 +
 +config TARGET_MX51_EFIKAMX
 +      bool "Support mx51_efikamx"
 +      select CPU_V7
 +
 +config TARGET_VISION2
 +      bool "Support vision2"
 +      select CPU_V7
 +
 +config TARGET_UDOO
 +      bool "Support udoo"
 +      select CPU_V7
 +
 +config TARGET_WANDBOARD
 +      bool "Support wandboard"
 +      select CPU_V7
 +
 +config TARGET_TITANIUM
 +      bool "Support titanium"
 +      select CPU_V7
 +
 +config TARGET_NITROGEN6X
 +      bool "Support nitrogen6x"
 +      select CPU_V7
 +
 +config TARGET_CGTQMX6EVAL
 +      bool "Support cgtqmx6eval"
 +      select CPU_V7
 +
 +config TARGET_EMBESTMX6BOARDS
 +      bool "Support embestmx6boards"
 +      select CPU_V7
 +
 +config TARGET_ARISTAINETOS
 +      bool "Support aristainetos"
 +      select CPU_V7
 +
 +config TARGET_MX6QARM2
 +      bool "Support mx6qarm2"
 +      select CPU_V7
 +
 +config TARGET_MX6QSABREAUTO
 +      bool "Support mx6qsabreauto"
 +      select CPU_V7
 +
 +config TARGET_MX6SABRESD
 +      bool "Support mx6sabresd"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_MX6SLEVK
 +      bool "Support mx6slevk"
 +      select CPU_V7
 +
 +config TARGET_MX6SXSABRESD
 +      bool "Support mx6sxsabresd"
 +      select CPU_V7
 +
 +config TARGET_GW_VENTANA
 +      bool "Support gw_ventana"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_HUMMINGBOARD
 +      bool "Support hummingboard"
 +      select CPU_V7
 +
 +config TARGET_KOSAGI_NOVENA
 +      bool "Support Kosagi Novena"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_TBS2910
 +      bool "Support tbs2910"
 +      select CPU_V7
 +
 +config TARGET_TQMA6
 +      bool "TQ Systems TQMa6 board"
 +      select CPU_V7
 +
 +config TARGET_OT1200
 +      bool "Bachmann OT1200"
 +      select CPU_V7
 +
 +config OMAP34XX
 +      bool "OMAP34XX SoC"
 +      select CPU_V7
 +
 +config OMAP44XX
 +      bool "OMAP44XX SoC"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config OMAP54XX
 +      bool "OMAP54XX SoC"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config RMOBILE
 +      bool "Renesas ARM SoCs"
 +      select CPU_V7
 +
 +config TARGET_CM_FX6
 +      bool "Support cm_fx6"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_SOCFPGA_CYCLONE5
 +      bool "Support socfpga_cyclone5"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config ARCH_SUNXI
 +      bool "Support sunxi (Allwinner) SoCs"
 +
 +config TARGET_SNOWBALL
 +      bool "Support snowball"
 +      select CPU_V7
 +
 +config TARGET_U8500_HREF
 +      bool "Support u8500_href"
 +      select CPU_V7
 +
 +config TARGET_VF610TWR
 +      bool "Support vf610twr"
 +      select CPU_V7
 +
 +config ZYNQ
 +      bool "Xilinx Zynq Platform"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TEGRA
 +      bool "NVIDIA Tegra"
 +      select SUPPORT_SPL
 +      select SPL
 +      select OF_CONTROL if !SPL_BUILD
 +      select CPU_ARM720T if SPL_BUILD
 +      select CPU_V7 if !SPL_BUILD
 +
 +config TARGET_VEXPRESS_AEMV8A
 +      bool "Support vexpress_aemv8a"
 +      select ARM64
 +
 +config TARGET_LS2085A_EMU
 +      bool "Support ls2085a_emu"
 +      select ARM64
 +
 +config TARGET_LS2085A_SIMU
 +      bool "Support ls2085a_simu"
 +      select ARM64
 +
 +config TARGET_LS1021AQDS
 +      bool "Support ls1021aqds"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_LS1021ATWR
 +      bool "Support ls1021atwr"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +
 +config TARGET_BALLOON3
 +      bool "Support balloon3"
 +      select CPU_PXA
 +
 +config TARGET_H2200
 +      bool "Support h2200"
 +      select CPU_PXA
 +
 +config TARGET_PALMLD
 +      bool "Support palmld"
 +      select CPU_PXA
 +
 +config TARGET_PALMTC
 +      bool "Support palmtc"
 +      select CPU_PXA
 +
 +config TARGET_PALMTREO680
 +      bool "Support palmtreo680"
 +      select CPU_PXA
 +      select SUPPORT_SPL
 +
 +config TARGET_PXA255_IDP
 +      bool "Support pxa255_idp"
 +      select CPU_PXA
 +
 +config TARGET_TRIZEPSIV
 +      bool "Support trizepsiv"
 +      select CPU_PXA
 +
 +config TARGET_VPAC270
 +      bool "Support vpac270"
 +      select CPU_PXA
 +      select SUPPORT_SPL
 +
 +config TARGET_XAENIAX
 +      bool "Support xaeniax"
 +      select CPU_PXA
 +
 +config TARGET_ZIPITZ2
 +      bool "Support zipitz2"
 +      select CPU_PXA
 +
 +config TARGET_LP8X4X
 +      bool "Support lp8x4x"
 +      select CPU_PXA
 +
 +config TARGET_COLIBRI_PXA270
 +      bool "Support colibri_pxa270"
 +      select CPU_PXA
 +
 +config TARGET_JORNADA
 +      bool "Support jornada"
 +      select CPU_SA1100
 +
 +config ARCH_UNIPHIER
 +      bool "Panasonic UniPhier platform"
 +      select CPU_V7
 +      select SUPPORT_SPL
 +      select SPL
 +      select OF_CONTROL if !SPL_BUILD
 +
 +endchoice
 +
 +source "arch/arm/cpu/arm926ejs/davinci/Kconfig"
 +
 +source "arch/arm/cpu/armv7/exynos/Kconfig"
 +
 +source "arch/arm/cpu/armv7/highbank/Kconfig"
 +
 +source "arch/arm/cpu/armv7/keystone/Kconfig"
 +
 +source "arch/arm/cpu/arm926ejs/kirkwood/Kconfig"
 +
 +source "arch/arm/cpu/arm926ejs/nomadik/Kconfig"
 +
 +source "arch/arm/cpu/armv7/omap3/Kconfig"
 +
 +source "arch/arm/cpu/armv7/omap4/Kconfig"
 +
 +source "arch/arm/cpu/armv7/omap5/Kconfig"
 +
 +source "arch/arm/cpu/arm926ejs/orion5x/Kconfig"
 +
 +source "arch/arm/cpu/armv7/rmobile/Kconfig"
 +
 +source "arch/arm/cpu/armv7/s5pc1xx/Kconfig"
 +
 +source "arch/arm/cpu/armv7/tegra-common/Kconfig"
 +
 +source "arch/arm/cpu/armv7/uniphier/Kconfig"
 +
 +source "arch/arm/cpu/arm926ejs/versatile/Kconfig"
 +
 +source "arch/arm/cpu/armv7/zynq/Kconfig"
 +
 +source "arch/arm/cpu/armv7/Kconfig"
 +
 +source "board/aristainetos/Kconfig"
 +source "board/BuR/kwb/Kconfig"
 +source "board/BuR/tseries/Kconfig"
 +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"
 +source "board/altera/socfpga/Kconfig"
 +source "board/armadeus/apf27/Kconfig"
 +source "board/armltd/integrator/Kconfig"
 +source "board/armltd/vexpress/Kconfig"
 +source "board/armltd/vexpress64/Kconfig"
 +source "board/atmel/at91rm9200ek/Kconfig"
 +source "board/atmel/at91sam9260ek/Kconfig"
 +source "board/atmel/at91sam9261ek/Kconfig"
 +source "board/atmel/at91sam9263ek/Kconfig"
 +source "board/atmel/at91sam9m10g45ek/Kconfig"
 +source "board/atmel/at91sam9n12ek/Kconfig"
 +source "board/atmel/at91sam9rlek/Kconfig"
 +source "board/atmel/at91sam9x5ek/Kconfig"
 +source "board/atmel/sama5d3_xplained/Kconfig"
 +source "board/atmel/sama5d3xek/Kconfig"
 +source "board/atmel/sama5d4_xplained/Kconfig"
 +source "board/atmel/sama5d4ek/Kconfig"
 +source "board/bachmann/ot1200/Kconfig"
 +source "board/balloon3/Kconfig"
 +source "board/barco/titanium/Kconfig"
 +source "board/bluegiga/apx4devkit/Kconfig"
 +source "board/bluewater/snapper9260/Kconfig"
 +source "board/boundary/nitrogen6x/Kconfig"
 +source "board/broadcom/bcm28155_ap/Kconfig"
 +source "board/broadcom/bcmcygnus/Kconfig"
 +source "board/broadcom/bcmnsp/Kconfig"
 +source "board/calao/sbc35_a9g20/Kconfig"
 +source "board/calao/tny_a9260/Kconfig"
 +source "board/calao/usb_a9263/Kconfig"
 +source "board/cirrus/edb93xx/Kconfig"
 +source "board/cm4008/Kconfig"
 +source "board/cm41xx/Kconfig"
 +source "board/compulab/cm_t335/Kconfig"
 +source "board/compulab/cm_fx6/Kconfig"
 +source "board/congatec/cgtqmx6eval/Kconfig"
 +source "board/creative/xfi3/Kconfig"
 +source "board/davedenx/qong/Kconfig"
 +source "board/denx/m28evk/Kconfig"
 +source "board/denx/m53evk/Kconfig"
 +source "board/egnite/ethernut5/Kconfig"
 +source "board/embest/mx6boards/Kconfig"
 +source "board/esd/meesc/Kconfig"
 +source "board/esd/otc570/Kconfig"
 +source "board/esg/ima3-mx53/Kconfig"
 +source "board/eukrea/cpu9260/Kconfig"
 +source "board/eukrea/cpuat91/Kconfig"
 +source "board/faraday/a320evb/Kconfig"
 +source "board/freescale/ls2085a/Kconfig"
 +source "board/freescale/ls1021aqds/Kconfig"
 +source "board/freescale/ls1021atwr/Kconfig"
 +source "board/freescale/mx23evk/Kconfig"
 +source "board/freescale/mx25pdk/Kconfig"
 +source "board/freescale/mx28evk/Kconfig"
 +source "board/freescale/mx31ads/Kconfig"
 +source "board/freescale/mx31pdk/Kconfig"
 +source "board/freescale/mx35pdk/Kconfig"
 +source "board/freescale/mx51evk/Kconfig"
 +source "board/freescale/mx53ard/Kconfig"
 +source "board/freescale/mx53evk/Kconfig"
 +source "board/freescale/mx53loco/Kconfig"
 +source "board/freescale/mx53smd/Kconfig"
 +source "board/freescale/mx6qarm2/Kconfig"
 +source "board/freescale/mx6qsabreauto/Kconfig"
 +source "board/freescale/mx6sabresd/Kconfig"
 +source "board/freescale/mx6slevk/Kconfig"
 +source "board/freescale/mx6sxsabresd/Kconfig"
 +source "board/freescale/vf610twr/Kconfig"
 +source "board/gateworks/gw_ventana/Kconfig"
 +source "board/genesi/mx51_efikamx/Kconfig"
 +source "board/gumstix/pepper/Kconfig"
 +source "board/h2200/Kconfig"
 +source "board/hale/tt01/Kconfig"
 +source "board/icpdas/lp8x4x/Kconfig"
 +source "board/imx31_phycore/Kconfig"
 +source "board/isee/igep0033/Kconfig"
 +source "board/jornada/Kconfig"
 +source "board/karo/tx25/Kconfig"
++source "board/karo/tx28/Kconfig"
++source "board/karo/tx48/Kconfig"
++source "board/karo/tx51/Kconfig"
++source "board/karo/tx53/Kconfig"
++source "board/karo/tx6/Kconfig"
 +source "board/kosagi/novena/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"
 +source "board/palmtc/Kconfig"
 +source "board/palmtreo680/Kconfig"
 +source "board/phytec/pcm051/Kconfig"
 +source "board/ppcag/bg0900/Kconfig"
 +source "board/pxa255_idp/Kconfig"
 +source "board/raspberrypi/rpi/Kconfig"
 +source "board/ronetix/pm9261/Kconfig"
 +source "board/ronetix/pm9263/Kconfig"
 +source "board/ronetix/pm9g45/Kconfig"
 +source "board/samsung/smdk2410/Kconfig"
 +source "board/sandisk/sansa_fuze_plus/Kconfig"
 +source "board/scb9328/Kconfig"
 +source "board/schulercontrol/sc_sps_1/Kconfig"
 +source "board/siemens/corvus/Kconfig"
 +source "board/siemens/draco/Kconfig"
 +source "board/siemens/pxm2/Kconfig"
 +source "board/siemens/rut/Kconfig"
 +source "board/siemens/taurus/Kconfig"
 +source "board/silica/pengwyn/Kconfig"
 +source "board/solidrun/hummingboard/Kconfig"
 +source "board/spear/spear300/Kconfig"
 +source "board/spear/spear310/Kconfig"
 +source "board/spear/spear320/Kconfig"
 +source "board/spear/spear600/Kconfig"
 +source "board/spear/x600/Kconfig"
 +source "board/st-ericsson/snowball/Kconfig"
 +source "board/st-ericsson/u8500/Kconfig"
 +source "board/st/stv0991/Kconfig"
 +source "board/sunxi/Kconfig"
 +source "board/syteco/jadecpu/Kconfig"
 +source "board/syteco/zmx25/Kconfig"
 +source "board/taskit/stamp9g20/Kconfig"
 +source "board/tbs/tbs2910/Kconfig"
 +source "board/ti/am335x/Kconfig"
 +source "board/ti/am43xx/Kconfig"
 +source "board/ti/ti814x/Kconfig"
 +source "board/ti/ti816x/Kconfig"
 +source "board/ti/tnetv107xevm/Kconfig"
 +source "board/timll/devkit3250/Kconfig"
 +source "board/toradex/colibri_pxa270/Kconfig"
 +source "board/tqc/tqma6/Kconfig"
 +source "board/trizepsiv/Kconfig"
 +source "board/ttcontrol/vision2/Kconfig"
 +source "board/udoo/Kconfig"
 +source "board/vpac270/Kconfig"
 +source "board/wandboard/Kconfig"
 +source "board/woodburn/Kconfig"
 +source "board/xaeniax/Kconfig"
 +source "board/zipitz2/Kconfig"
 +
 +source "arch/arm/Kconfig.debug"
 +
 +endmenu
diff --combined arch/arm/config.mk
index 0667984b697d62845cb013ba3376cfc5ca01bbf3,f9908e5ae63313af28994519855dde404d6688eb..51829495682045cfff5fb1d1ebac921199798534
@@@ -5,8 -5,10 +5,8 @@@
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
 -CROSS_COMPILE ?= arm-linux-
 -
  ifndef CONFIG_STANDALONE_LOAD_ADDR
 -ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
 +ifneq ($(CONFIG_OMAP_COMMON),)
  CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
  else
  CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
@@@ -14,21 -16,16 +14,21 @@@ endi
  endif
  
  LDFLAGS_FINAL += --gc-sections
 -PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
 +PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
 +                   -fno-common -ffixed-r9
 +PLATFORM_RELFLAGS += $(call cc-option, -msoft-float) \
 +      $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
  
  # Support generic board on ARM
  __HAVE_ARCH_GENERIC_BOARD := y
  
 -PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
 +PLATFORM_CPPFLAGS += -D__ARM__
  
  # Choose between ARM/Thumb instruction sets
  ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
 -PF_CPPFLAGS_ARM := $(call cc-option, -mthumb -mthumb-interwork,\
 +AFLAGS_IMPLICIT_IT    := $(call as-option,-Wa$(comma)-mimplicit-it=always)
 +PF_CPPFLAGS_ARM               := $(AFLAGS_IMPLICIT_IT) \
 +                      $(call cc-option, -mthumb -mthumb-interwork,\
                        $(call cc-option,-marm,)\
                        $(call cc-option,-mno-thumb-interwork,)\
                )
@@@ -39,20 -36,10 +39,20 @@@ endi
  
  # Only test once
  ifneq ($(CONFIG_SPL_BUILD),y)
 -ALL-$(CONFIG_SYS_THUMB_BUILD) += checkthumb
 +ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
 +archprepare: checkthumb
 +
 +checkthumb:
 +      @if test "$(call cc-version)" -lt "0404"; then \
 +              echo -n '*** Your GCC does not produce working '; \
 +              echo 'binaries in THUMB mode.'; \
 +              echo '*** Your board is configured for THUMB mode.'; \
 +              false; \
 +      fi
 +endif
  endif
  
- # Try if EABI is supported, else fall back to old API,
+ # Try if EABI is supported, else fall back to old ABI,
  # i. e. for example:
  # - with ELDK 4.2 (EABI supported), use:
  #     -mabi=aapcs-linux
@@@ -77,8 -64,13 +77,8 @@@ ifneq (,$(findstring -mabi=aapcs-linux,
  # times. Also, the prefix needs to be different based on whether
  # CONFIG_SPL_BUILD is defined or not. 'filter-out' the existing entry
  # before adding the correct one.
 -ifdef CONFIG_SPL_BUILD
 -PLATFORM_LIBS := $(SPLTREE)/arch/arm/lib/eabi_compat.o \
 -      $(filter-out %/arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS))
 -else
 -PLATFORM_LIBS := $(OBJTREE)/arch/arm/lib/eabi_compat.o \
 -      $(filter-out %/arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS))
 -endif
 +PLATFORM_LIBS := arch/arm/lib/eabi_compat.o \
 +      $(filter-out arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS))
  endif
  
  # needed for relocation
@@@ -102,36 -94,7 +102,36 @@@ PLATFORM_RELFLAGS += -fno-optimize-sibl
  endif
  endif
  
 -# check that only R_ARM_RELATIVE relocations are generated
  ifneq ($(CONFIG_SPL_BUILD),y)
 -ALL-y += checkarmreloc
 +# Check that only R_ARM_RELATIVE relocations are generated.
 +ALL-y += checkarmreloc
 +# The movt / movw can hardcode 16 bit parts of the addresses in the
 +# instruction. Relocation is not supported for that case, so disable
 +# such usage by requiring word relocations.
 +PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations)
 +endif
 +
 +# limit ourselves to the sections we want in the .bin.
 +ifdef CONFIG_ARM64
 +OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
 +else
 +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
 +endif
 +
 +ifdef CONFIG_OF_EMBED
 +OBJCOPYFLAGS += -j .dtb.init.rodata
 +endif
 +
 +ifneq ($(CONFIG_IMX_CONFIG),)
 +ifdef CONFIG_SPL
 +ifndef CONFIG_SPL_BUILD
 +ALL-y += SPL
 +endif
 +else
 +ifeq ($(CONFIG_OF_SEPARATE),y)
 +ALL-y += u-boot-dtb.imx
 +else
 +ALL-y += u-boot.imx
 +endif
 +endif
  endif
index ef130aea426975babb926a48d0da0e863ec65638,6f09f627ae9ce86efdc07a49c90244101c9c71a4..f3c1575a36897bff3c6913be37309d70c1db120f
@@@ -26,6 -26,31 +26,31 @@@ DECLARE_GLOBAL_DATA_PTR
  /* Lowlevel init isn't used on i.MX28, so just have a dummy here */
  inline void lowlevel_init(void) {}
  
+ #define BOOT_CAUSE_MASK               (RTC_PERSISTENT0_EXTERNAL_RESET |       \
+                               RTC_PERSISTENT0_ALARM_WAKE |            \
+                               RTC_PERSISTENT0_THERMAL_RESET)
+ static int wait_rtc_stat(u32 mask)
+ {
+       int timeout = 5000;
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       u32 old_val = readl(&rtc_regs->hw_rtc_stat);
+       debug("stat=%x\n", old_val);
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               if (val != old_val) {
+                       old_val = val;
+                       debug("stat: %x -> %x\n", old_val, val);
+               }
+               udelay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+ }
  void reset_cpu(ulong ignored) __attribute__((noreturn));
  
  void reset_cpu(ulong ignored)
@@@ -34,6 -59,7 +59,7 @@@
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
        struct mxs_lcdif_regs *lcdif_regs =
                (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+       u32 reg;
  
        /*
         * Shut down the LCD controller as it interferes with BootROM boot mode
         */
        writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
  
-       /* Wait 1 uS before doing the actual watchdog reset */
+       reg = readl(&rtc_regs->hw_rtc_persistent0);
+       if (reg & BOOT_CAUSE_MASK) {
+               writel(reg & ~BOOT_CAUSE_MASK, &rtc_regs->hw_rtc_persistent0);
+               wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0);
+       }
+       /* Wait 1 mS before doing the actual watchdog reset */
        writel(1, &rtc_regs->hw_rtc_watchdog);
        writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
  
@@@ -77,17 -109,12 +109,21 @@@ void enable_caches(void
  void mx28_fixup_vt(uint32_t start_addr)
  {
        /* ldr pc, [pc, #0x18] */
-       const uint32_t ldr_pc = 0xe59ff018;
        /* Jumptable location is 0x0 */
-       uint32_t *vt = (uint32_t *)0x0;
-       int i;
+       uint32_t *vt = (uint32_t *)0x20;
+       uint32_t cr = get_cr();
  
++<<<<<<< HEAD
 +      for (i = 0; i < 8; i++) {
 +              /* cppcheck-suppress nullPointer */
 +              vt[i] = ldr_pc;
 +              /* cppcheck-suppress nullPointer */
 +              vt[i + 8] = start_addr + (4 * i);
 +      }
++=======
+       memcpy(vt, (void *)start_addr + 0x20, 32);
+       set_cr(cr & ~CR_V);
++>>>>>>> karo-tx-uboot
  }
  
  #ifdef        CONFIG_ARCH_MISC_INIT
@@@ -98,6 -125,7 +134,7 @@@ int arch_misc_init(void
  }
  #endif
  
+ #ifdef CONFIG_ARCH_CPU_INIT
  int arch_cpu_init(void)
  {
        struct mxs_clkctrl_regs *clkctrl_regs =
  
        return 0;
  }
+ #endif
  
  #if defined(CONFIG_DISPLAY_CPUINFO)
  static const char *get_cpu_type(void)
@@@ -196,12 -225,21 +234,21 @@@ int print_cpuinfo(void
  }
  #endif
  
+ #define pr_clk(n, c) {                                                \
+       unsigned long clk = c;  \
+       printf("%-5s  %3lu.%03lu MHz\n", #n ":", clk / 1000000, \
+               clk / 1000 % 1000);                             \
+ }
  int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  {
-       printf("CPU:   %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
-       printf("BUS:   %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
-       printf("EMI:   %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
-       printf("GPMI:  %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
+       pr_clk(CPU, mxc_get_clock(MXC_ARM_CLK));
+       pr_clk(APBH, mxc_get_clock(MXC_AHB_CLK));
+       pr_clk(APBX, mxc_get_clock(MXC_XBUS_CLK));
+       pr_clk(IO0, mxc_get_clock(MXC_IO0_CLK) * 1000);
+       pr_clk(IO1, mxc_get_clock(MXC_IO1_CLK) * 1000);
+       pr_clk(EMI, mxc_get_clock(MXC_EMI_CLK) * 1000000);
+       pr_clk(GPMI, mxc_get_clock(MXC_GPMI_CLK));
        return 0;
  }
  
@@@ -225,13 -263,17 +272,17 @@@ int cpu_eth_init(bd_t *bis
  
        udelay(10);
  
+       /*
+        * Enable pad output; must be done BEFORE enabling PLL
+        * according to i.MX28 Ref. Manual Rev. 1, 2010 p. 883
+        */
+       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
        /* Gate on ENET PLL */
        writel(CLKCTRL_PLL2CTRL0_CLKGATE,
                &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
  
-       /* Enable pad output */
-       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+       udelay(6000);
        return 0;
  }
  #endif
index d29b9aaf3da576889bfb02620e8e7aeb106b8db7,74bc009dc5b0bc1a5aba1fc07d54a55036408a19..49d50196e005874007e652f80ca9c5c11f7aee76
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/sys_proto.h>
  #include <asm/gpio.h>
 +#include <linux/compiler.h>
  
  #include "mxs_init.h"
  
 +DECLARE_GLOBAL_DATA_PTR;
 +static gd_t gdata __section(".data");
 +#ifdef CONFIG_SPL_SERIAL_SUPPORT
 +static bd_t bdata __section(".data");
 +#endif
 +
  /*
   * This delay function is intended to be used only in early stage of boot, where
   * clock are not set up yet. The timer used here is reset on every boot and
   * takes a few seconds to roll. The boot doesn't take that long, so to keep the
   * code simple, it doesn't take rolling into consideration.
   */
+ /*
+  * There's nothing to be taken into consideration for the rollover.
+  * Two's complement arithmetic used correctly does all that's needed
+  * automagically.
+  */
  void early_delay(int delay)
  {
        struct mxs_digctl_regs *digctl_regs =
                (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+       u32 start = readl(&digctl_regs->hw_digctl_microseconds);
  
-       uint32_t st = readl(&digctl_regs->hw_digctl_microseconds);
-       st += delay;
-       while (st > readl(&digctl_regs->hw_digctl_microseconds))
-               ;
+       while (readl(&digctl_regs->hw_digctl_microseconds) - start < delay);
  }
  
  #define       MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
@@@ -109,45 -105,14 +112,45 @@@ static uint8_t mxs_get_bootmode_index(v
        return i;
  }
  
 -void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
 -                      const unsigned int iomux_size)
 +static void mxs_spl_fixup_vectors(void)
 +{
 +      /*
 +       * Copy our vector table to 0x0, since due to HAB, we cannot
 +       * be loaded to 0x0. We want to have working vectoring though,
 +       * thus this fixup. Our vectoring table is PIC, so copying is
 +       * fine.
 +       */
 +      extern uint32_t _start;
 +
 +      /* cppcheck-suppress nullPointer */
 +      memcpy(0x0, &_start, 0x60);
 +}
 +
 +static void mxs_spl_console_init(void)
 +{
 +#ifdef CONFIG_SPL_SERIAL_SUPPORT
 +      gd->bd = &bdata;
 +      gd->baudrate = CONFIG_BAUDRATE;
 +      serial_init();
 +      gd->have_console = 1;
 +#endif
 +}
 +
 +void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
 +                       const iomux_cfg_t *iomux_setup,
 +                       const unsigned int iomux_size)
  {
        struct mxs_spl_data *data = (struct mxs_spl_data *)
                ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
        uint8_t bootmode = mxs_get_bootmode_index();
 +      gd = &gdata;
 +
 +      mxs_spl_fixup_vectors();
  
        mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
 +
 +      mxs_spl_console_init();
 +
        mxs_power_init();
  
        mxs_mem_init();
        mxs_power_wait_pswitch();
  }
  
- /* Support aparatus */
+ /* Support apparatus */
  inline void board_init_f(unsigned long bootflag)
  {
        for (;;)
index 97ef67d8c5843b06fcd6c7d903cd3d4cb21d976b,44cf84d5a9822d09840c61a0b130720f8ba831f9..d5842e68133e880ba142c65b45512f9912827a54
@@@ -158,18 -158,17 +158,17 @@@ static void mxs_mem_init_clock(void
        writeb(CLKCTRL_FRAC_CLKGATE,
                &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
  
-       early_delay(11000);
  
        /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
        writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
                (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
                &clkctrl_regs->hw_clkctrl_emi);
+       while (readl(&clkctrl_regs->hw_clkctrl_emi) & CLKCTRL_EMI_BUSY_REF_EMI)
+               ;
  
        /* Unbypass EMI */
        writel(CLKCTRL_CLKSEQ_BYPASS_EMI,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-       early_delay(10000);
  }
  
  static void mxs_mem_setup_cpu_and_hbus(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
  
        /* HBUS = 151MHz */
-       writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set);
-       writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK,
-               &clkctrl_regs->hw_clkctrl_hbus_clr);
-       early_delay(10000);
+       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_hbus,
+                       CLKCTRL_HBUS_DIV_MASK,
+                       3 << CLKCTRL_HBUS_DIV_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_hbus) & CLKCTRL_HBUS_ASM_BUSY)
+               ;
  
        /* CPU clock divider = 1 */
        clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
-                       CLKCTRL_CPU_DIV_CPU_MASK, 1);
+                       CLKCTRL_CPU_DIV_CPU_MASK,
+                       1 << CLKCTRL_CPU_DIV_CPU_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_cpu) & CLKCTRL_CPU_BUSY_REF_CPU)
+               ;
  
        /* Disable CPU bypass */
        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-       early_delay(15000);
  }
  
static void mxs_mem_setup_vdda(void)
void data_abort_memdetect_handler(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-       writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vddactrl);
+       asm volatile("subs pc, lr, #4");
  }
  
  uint32_t mxs_mem_get_size(void)
  {
        uint32_t sz, da;
        uint32_t *vt = (uint32_t *)0x20;
-       /* The following is "subs pc, r14, #4", used as return from DABT. */
-       const uint32_t data_abort_memdetect_handler = 0xe25ef004;
+       unsigned long cr;
+       /* move vector table to low memory */
+       asm volatile(
+               "mrc p15, 0, %0, c1, c0, 0\n"
+               "bic r7, %0, #(1 << 13)\n"
+               "mcr p15, 0, r7, c1, c0, 0\n"
+               : "=r"(cr) : : "r7");
  
        /* Replace the DABT handler. */
        da = vt[4];
-       vt[4] = data_abort_memdetect_handler;
+       vt[4] = (uint32_t)data_abort_memdetect_handler;
  
        sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
  
        /* Restore the old DABT handler. */
        vt[4] = da;
+       asm volatile("mcr p15, 0, %0, c1, c0, 0\n" : : "r"(cr));
  
        return sz;
  }
@@@ -240,14 -241,9 +241,14 @@@ static void mx23_mem_setup_vddmem(void
        struct mxs_power_regs *power_regs =
                (struct mxs_power_regs *)MXS_POWER_BASE;
  
 +      /* We must wait before and after disabling the current limiter! */
 +      early_delay(10000);
 +
        clrbits_le32(&power_regs->hw_power_vddmemctrl,
                POWER_VDDMEMCTRL_ENABLE_ILIMIT);
  
 +      early_delay(10000);
 +
  }
  
  static void mx23_mem_init(void)
        setbits_le32(MXS_DRAM_BASE + 0x20, 1 << 16);
  
        clrbits_le32(MXS_DRAM_BASE + 0x40, 1 << 17);
 -      early_delay(20000);
 +
 +      /* Wait for EMI_STAT bit DRAM_HALTED */
 +      for (;;) {
 +              if (!(readl(MXS_EMI_BASE + 0x10) & (1 << 1)))
 +                      break;
 +              early_delay(1000);
 +      }
  
        /* Adjust EMI port priority. */
        clrsetbits_le32(0x80020000, 0x1f << 16, 0x2);
@@@ -328,15 -318,11 +329,11 @@@ void mxs_mem_init(void
  
        mxs_mem_init_clock();
  
-       mxs_mem_setup_vdda();
  #if defined(CONFIG_MX23)
        mx23_mem_init();
  #elif defined(CONFIG_MX28)
        mx28_mem_init();
  #endif
  
-       early_delay(10000);
        mxs_mem_setup_cpu_and_hbus();
  }
index 1c54ab7de3bfc3726b1c823e47500a462607b1a4,ff4ff13dd9b82b1e543419d3eeb071ce749cb554..161a1e157ac5ae369f3e64e2927757e4e72432b0
  
  #include "mxs_init.h"
  
+ #ifdef CONFIG_SYS_SPL_VDDD_VAL
+ #define VDDD_VAL      CONFIG_SYS_SPL_VDDD_VAL
+ #else
+ #define VDDD_VAL      1350
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDIO_VAL
+ #define VDDIO_VAL     CONFIG_SYS_SPL_VDDIO_VAL
+ #else
+ #define VDDIO_VAL     3300
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDA_VAL
+ #define VDDA_VAL      CONFIG_SYS_SPL_VDDA_VAL
+ #else
+ #define VDDA_VAL      1800
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDMEM_VAL
+ #define VDDMEM_VAL    CONFIG_SYS_SPL_VDDMEM_VAL
+ #else
+ #define VDDMEM_VAL    1700
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDD_BO_VAL
+ #define VDDD_BO_VAL   CONFIG_SYS_SPL_VDDD_BO_VAL
+ #else
+ #define VDDD_BO_VAL   150
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDIO_BO_VAL
+ #define VDDIO_BO_VAL  CONFIG_SYS_SPL_VDDIO_BO_VAL
+ #else
+ #define VDDIO_BO_VAL  150
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDA_BO_VAL
+ #define VDDA_BO_VAL   CONFIG_SYS_SPL_VDDA_BO_VAL
+ #else
+ #define VDDA_BO_VAL   175
+ #endif
+ #ifdef CONFIG_SYS_SPL_VDDMEM_BO_VAL
+ #define VDDMEM_BO_VAL CONFIG_SYS_SPL_VDDMEM_BO_VAL
+ #else
+ #define VDDMEM_BO_VAL 25
+ #endif
+ #ifdef CONFIG_SYS_SPL_BATT_BO_LEVEL
+ #if CONFIG_SYS_SPL_BATT_BO_LEVEL < 2400 || CONFIG_SYS_SPL_BATT_BO_LEVEL > 3640
+ #error CONFIG_SYS_SPL_BATT_BO_LEVEL out of range
+ #endif
+ #define BATT_BO_VAL   (((CONFIG_SYS_SPL_BATT_BO_LEVEL) - 2400) / 40)
+ #else
+ /* Brownout default at 3V */
+ #define BATT_BO_VAL   ((3000 - 2400) / 40)
+ #endif
+ #ifdef CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+ static const int fixed_batt_supply = 1;
+ #else
+ static const int fixed_batt_supply;
+ #endif
+ static struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
 +/**
 + * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
 + *
 + * This function switches the CPU core clock from PLL to 24MHz XTAL
 + * oscilator. This is necessary if the PLL is being reconfigured to
 + * prevent crash of the CPU core.
 + */
  static void mxs_power_clock2xtal(void)
  {
        struct mxs_clkctrl_regs *clkctrl_regs =
                &clkctrl_regs->hw_clkctrl_clkseq_set);
  }
  
 +/**
 + * mxs_power_clock2pll() - Switch CPU core clock source to PLL
 + *
 + * This function switches the CPU core clock from 24MHz XTAL oscilator
 + * to PLL. This can only be called once the PLL has re-locked and once
 + * the PLL is stable after reconfiguration.
 + */
  static void mxs_power_clock2pll(void)
  {
        struct mxs_clkctrl_regs *clkctrl_regs =
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
  }
  
- static void mxs_power_set_auto_restart(void)
+ static int mxs_power_wait_rtc_stat(u32 mask)
+ {
+       int timeout = 5000; /* 3 ms according to i.MX28 Ref. Manual */
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               early_delay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+ }
 +/**
 + * mxs_power_set_auto_restart() - Set the auto-restart bit
 + *
 + * This function ungates the RTC block and sets the AUTO_RESTART
 + * bit to work around a design bug on MX28EVK Rev. A .
 + */
+ static int mxs_power_set_auto_restart(int on)
  {
-       struct mxs_rtc_regs *rtc_regs =
-               (struct mxs_rtc_regs *)MXS_RTC_BASE;
-       writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
-               ;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
  
-       writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
-               ;
 -      /*
 -       * Due to the hardware design bug of mx28 EVK-A
 -       * we need to set the AUTO_RESTART bit.
 -       */
+       if (mxs_power_wait_rtc_stat(RTC_STAT_STALE_REGS_PERSISTENT0))
+               return 1;
  
-               return;
 +      /* Do nothing if flag already set */
 +      if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
++              return 0;
 +
+       if ((!(readl(&rtc_regs->hw_rtc_persistent0) &
+                               RTC_PERSISTENT0_AUTO_RESTART) ^ !on) == 0)
+               return 0;
  
-       setbits_le32(&rtc_regs->hw_rtc_persistent0,
-                       RTC_PERSISTENT0_AUTO_RESTART);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
-               ;
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+       clrsetbits_le32(&rtc_regs->hw_rtc_persistent0,
+                       !on * RTC_PERSISTENT0_AUTO_RESTART,
+                       !!on * RTC_PERSISTENT0_AUTO_RESTART);
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+       return 0;
  }
  
 +/**
 + * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter
 + *
 + * This function configures the VDDIO, VDDA and VDDD linear regulators output
 + * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching
 + * converter. This is the recommended setting for the case where we use both
 + * linear regulators and DC-DC converter to power the VDDIO rail.
 + */
  static void mxs_power_set_linreg(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /* Set linear regulator 25mV below switching converter */
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
  }
  
 +/**
 + * mxs_get_batt_volt() - Measure battery input voltage
 + *
 + * This function retrieves the battery input voltage and returns it.
 + */
  static int mxs_get_batt_volt(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = readl(&power_regs->hw_power_battmonitor);
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
        volt *= 8;
        return volt;
  }
  
 +/**
 + * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot
 + *
 + * This function checks if the battery input voltage is higher than 3.6V and
 + * therefore allows the system to successfully boot using this power source.
 + */
  static int mxs_is_batt_ready(void)
  {
        return (mxs_get_batt_volt() >= 3600);
  }
  
 +/**
 + * mxs_is_batt_good() - Test if battery is operational at all
 + *
 + * This function starts recharging the battery and tests if the input current
 + * provided by the 5V input recharging the battery is also sufficient to power
 + * the DC-DC converter.
 + */
  static int mxs_is_batt_good(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = mxs_get_batt_volt();
  
        if ((volt >= 2400) && (volt <= 4300))
        return 0;
  }
  
 +/**
 + * mxs_power_setup_5v_detect() - Start the 5V input detection comparator
 + *
 + * This function enables the 5V detection comparator and sets the 5V valid
 + * threshold to 4.4V . We use 4.4V threshold here to make sure that even
 + * under high load, the voltage drop on the 5V input won't be so critical
 + * to cause undervolt on the 4P2 linear regulator supplying the DC-DC
 + * converter and thus making the system crash.
 + */
  static void mxs_power_setup_5v_detect(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /* Start 5V detection */
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
                        POWER_5VCTRL_PWRUP_VBUS_CMPS);
  }
  
 +/**
 + * mxs_src_power_init() - Preconfigure the power block
 + *
 + * This function configures reasonable values for the DC-DC control loop
 + * and battery monitor.
 + */
  static void mxs_src_power_init(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /* Improve efficieny and reduce transient ripple */
        writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
                POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
                        POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
                        0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
  
-       setbits_le32(&power_regs->hw_power_battmonitor,
+       if (!fixed_batt_supply) {
+               /* FIXME: This requires the LRADC to be set up! */
+               setbits_le32(&power_regs->hw_power_battmonitor,
                        POWER_BATTMONITOR_EN_BATADJ);
+       } else {
+               clrbits_le32(&power_regs->hw_power_battmonitor,
+                       POWER_BATTMONITOR_EN_BATADJ);
+       }
  
        /* Increase the RCSCALE level for quick DCDC response to dynamic load */
        clrsetbits_le32(&power_regs->hw_power_loopctrl,
        clrsetbits_le32(&power_regs->hw_power_minpwr,
                        POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
  
-       /* 5V to battery handoff ... FIXME */
-       setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
-       early_delay(30);
-       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       if (!fixed_batt_supply) {
+               /* 5V to battery handoff ... FIXME */
+               setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+               early_delay(30);
+               clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       }
  }
  
 +/**
 + * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator
 + *
 + * This function configures the necessary parameters for the 4P2 linear
 + * regulator to supply the DC-DC converter from 5V input.
 + */
  static void mxs_power_init_4p2_params(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
                0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
  }
  
 +/**
 + * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2
 + * @xfer:     Select if the input shall be enabled or disabled
 + *
 + * This function enables or disables the 4P2 input into the DC-DC converter.
 + */
  static void mxs_enable_4p2_dcdc_input(int xfer)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
  
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
  }
  
 +/**
 + * mxs_power_init_4p2_regulator() - Start the 4P2 regulator
 + *
 + * This function enables the 4P2 regulator and switches the DC-DC converter
 + * to use the 4P2 input.
 + */
  static void mxs_power_init_4p2_regulator(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, tmp2;
  
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
        writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
  }
  
 +/**
 + * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source
 + *
 + * This function configures the DC-DC converter to be supplied from the 4P2
 + * linear regulator.
 + */
  static void mxs_power_init_dcdc_4p2_source(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
                hang();
        }
  }
  
 +/**
 + * mxs_power_enable_4p2() - Power up the 4P2 regulator
 + *
 + * This function drives the process of powering up the 4P2 linear regulator
 + * and switching the DC-DC converter input over to the 4P2 linear regulator.
 + */
  static void mxs_power_enable_4p2(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
  
                        &power_regs->hw_power_charge_clr);
  }
  
 +/**
 + * mxs_boot_valid_5v() - Boot from 5V supply
 + *
 + * This function configures the power block to boot from valid 5V input.
 + * This is called only if the 5V is reliable and can properly supply the
 + * CPU. This function proceeds to configure the 4P2 converter to be supplied
 + * from the 5V input.
 + */
  static void mxs_boot_valid_5v(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
        mxs_power_enable_4p2();
  }
  
 +/**
 + * mxs_powerdown() - Shut down the system
 + *
 + * This function powers down the CPU completely.
 + */
  static void mxs_powerdown(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
        writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
                &power_regs->hw_power_reset);
  }
  
 +/**
 + * mxs_batt_boot() - Configure the power block to boot from battery input
 + *
 + * This function configures the power block to boot from the battery voltage
 + * supply.
 + */
  static void mxs_batt_boot(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
  
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
                0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 +
 +      mxs_power_enable_4p2();
  }
  
 +/**
 + * mxs_handle_5v_conflict() - Test if the 5V input is reliable
 + *
 + * This function tests if the 5V input can reliably supply the system. If it
 + * can, then proceed to configuring the system to boot from 5V source, otherwise
 + * try booting from battery supply. If we can not boot from battery supply
 + * either, shut down the system.
 + */
  static void mxs_handle_5v_conflict(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
  
        setbits_le32(&power_regs->hw_power_vddioctrl,
        }
  }
  
 +/**
 + * mxs_5v_boot() - Configure the power block to boot from 5V input
 + *
 + * This function handles configuration of the power block when supplied by
 + * a 5V input.
 + */
  static void mxs_5v_boot(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        /*
         * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
         * but their implementation always returns 1 so we omit it here.
        mxs_handle_5v_conflict();
  }
  
 -static void mxs_fixed_batt_boot(void)
 +/**
 + * mxs_init_batt_bo() - Configure battery brownout threshold
 + *
 + * This function configures the battery input brownout threshold. The value
 + * at which the battery brownout happens is configured to 3.0V in the code.
 + */
 +static void mxs_init_batt_bo(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
+       writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_ENABLE_DCDC |
+               POWER_5VCTRL_ILIMIT_EQ_ZERO |
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET |
+               POWER_VDDDCTRL_ENABLE_LINREG |
+               POWER_VDDDCTRL_DISABLE_STEPPING);
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+               POWER_VDDACTRL_DISABLE_STEPPING);
+       clrbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET |
+               POWER_VDDIOCTRL_DISABLE_STEPPING);
  
-       /* Brownout at 3V */
+       /* Stop 5V detection */
+       writel(POWER_5VCTRL_PWRUP_VBUS_CMPS,
+               &power_regs->hw_power_5vctrl_clr);
+ }
+ static void mxs_init_batt_bo(void)
+ {
        clrsetbits_le32(&power_regs->hw_power_battmonitor,
                POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
-               15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
+               BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
  
        writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
  }
  
 +/**
 + * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter
 + *
 + * This function turns off the VDDD linear regulator and therefore makes
 + * the VDDD rail be supplied only by the DC-DC converter.
 + */
  static void mxs_switch_vddd_to_dcdc_source(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
                POWER_VDDDCTRL_DISABLE_STEPPING);
  }
  
 +/**
 + * mxs_power_configure_power_source() - Configure power block source
 + *
 + * This function is the core of the power configuration logic. The function
 + * selects the power block input source and configures the whole power block
 + * accordingly. After the configuration is complete and the system is stable
 + * again, the function switches the CPU clock source back to PLL. Finally,
 + * the function switches the voltage rails to DC-DC converter.
 + */
  static void mxs_power_configure_power_source(void)
  {
-       int batt_ready, batt_good;
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        struct mxs_lradc_regs *lradc_regs =
                (struct mxs_lradc_regs *)MXS_LRADC_BASE;
  
        mxs_src_power_init();
  
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
-               batt_ready = mxs_is_batt_ready();
-               if (batt_ready) {
-                       /* 5V source detected, good battery detected. */
-                       mxs_batt_boot();
-               } else {
-                       batt_good = mxs_is_batt_good();
-                       if (!batt_good) {
-                               /* 5V source detected, bad battery detected. */
-                               writel(LRADC_CONVERSION_AUTOMATIC,
-                                       &lradc_regs->hw_lradc_conversion_clr);
-                               clrbits_le32(&power_regs->hw_power_battmonitor,
-                                       POWER_BATTMONITOR_BATT_VAL_MASK);
+       if (!fixed_batt_supply) {
+               if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+                       if (mxs_is_batt_ready()) {
+                               /* 5V source detected, good battery detected. */
+                               mxs_batt_boot();
+                       } else {
+                               if (!mxs_is_batt_good()) {
+                                       /* 5V source detected, bad battery detected. */
+                                       writel(LRADC_CONVERSION_AUTOMATIC,
+                                               &lradc_regs->hw_lradc_conversion_clr);
+                                       clrbits_le32(&power_regs->hw_power_battmonitor,
+                                               POWER_BATTMONITOR_BATT_VAL_MASK);
+                               }
+                               mxs_5v_boot();
                        }
-                       mxs_5v_boot();
+               } else {
+                       /* 5V not detected, booting from battery. */
+                       mxs_batt_boot();
                }
        } else {
-               /* 5V not detected, booting from battery. */
-               mxs_batt_boot();
+               mxs_fixed_batt_boot();
        }
  
        mxs_power_clock2pll();
  #endif
  }
  
 +/**
 + * mxs_enable_output_rail_protection() - Enable power rail protection
 + *
 + * This function enables overload protection on the power rails. This is
 + * triggered if the power rails' voltage drops rapidly due to overload and
 + * in such case, the supply to the powerrail is cut-off, protecting the
 + * CPU from damage. Note that under such condition, the system will likely
 + * crash or misbehave.
 + */
  static void mxs_enable_output_rail_protection(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
  
                        POWER_VDDIOCTRL_PWDN_BRNOUT);
  }
  
 +/**
 + * mxs_get_vddio_power_source_off() - Get VDDIO rail power source
 + *
 + * This function tests if the VDDIO rail is supplied by linear regulator
 + * or by the DC-DC converter. Returns 1 if powered by linear regulator,
 + * returns 0 if powered by the DC-DC converter.
 + */
  static int mxs_get_vddio_power_source_off(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
  
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       if ((readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) &&
+               !(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ILIMIT_EQ_ZERO)) {
                tmp = readl(&power_regs->hw_power_vddioctrl);
                if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
                        if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
        }
  
        return 0;
  }
  
 +/**
 + * mxs_get_vddd_power_source_off() - Get VDDD rail power source
 + *
 + * This function tests if the VDDD rail is supplied by linear regulator
 + * or by the DC-DC converter. Returns 1 if powered by linear regulator,
 + * returns 0 if powered by the DC-DC converter.
 + */
  static int mxs_get_vddd_power_source_off(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
  
        tmp = readl(&power_regs->hw_power_vdddctrl);
        return 0;
  }
  
+ static int mxs_get_vdda_power_source_off(void)
+ {
+       uint32_t tmp;
+       tmp = readl(&power_regs->hw_power_vddactrl);
+       if (tmp & POWER_VDDACTRL_DISABLE_FET) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_0STEPS) {
+                       return 1;
+               }
+       }
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               if (!(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+                       return 1;
+               }
+       }
+       if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW) {
+                       return 1;
+               }
+       }
+       return 0;
+ }
  struct mxs_vddx_cfg {
        uint32_t                *reg;
        uint8_t                 step_mV;
        uint16_t                lowest_mV;
+       uint16_t                highest_mV;
        int                     (*powered_by_linreg)(void);
        uint32_t                trg_mask;
        uint32_t                bo_irq;
        uint32_t                bo_offset_offset;
  };
  
+ #define POWER_REG(n)          &((struct mxs_power_regs *)MXS_POWER_BASE)->n
  static const struct mxs_vddx_cfg mxs_vddio_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddioctrl),
+       .reg                    = POWER_REG(hw_power_vddioctrl),
  #if defined(CONFIG_MX23)
        .step_mV                = 25,
  #else
        .step_mV                = 50,
  #endif
        .lowest_mV              = 2800,
+       .highest_mV             = 3600,
        .powered_by_linreg      = mxs_get_vddio_power_source_off,
        .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
  };
  
  static const struct mxs_vddx_cfg mxs_vddd_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vdddctrl),
+       .reg                    = POWER_REG(hw_power_vdddctrl),
        .step_mV                = 25,
        .lowest_mV              = 800,
+       .highest_mV             = 1575,
        .powered_by_linreg      = mxs_get_vddd_power_source_off,
        .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
        .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
  };
  
+ static const struct mxs_vddx_cfg mxs_vdda_cfg = {
+       .reg                    = POWER_REG(hw_power_vddactrl),
+       .step_mV                = 50,
+       .lowest_mV              = 2800,
+       .highest_mV             = 3600,
+       .powered_by_linreg      = mxs_get_vdda_power_source_off,
+       .trg_mask               = POWER_VDDACTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDA_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDA_BO,
+       .bo_offset_mask         = POWER_VDDACTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDACTRL_BO_OFFSET_OFFSET,
+ };
  #ifdef CONFIG_MX23
  static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddmemctrl),
+       .reg                    = POWER_REG(hw_power_vddmemctrl),
        .step_mV                = 50,
-       .lowest_mV              = 1700,
+       .lowest_mV              = 1500,
+       .highest_mV             = 1700,
        .powered_by_linreg      = NULL,
        .trg_mask               = POWER_VDDMEMCTRL_TRG_MASK,
        .bo_irq                 = 0,
  };
  #endif
  
 +/**
 + * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail
 + * @cfg:              Configuration data of the DC-DC converter rail
 + * @new_target:               New target voltage of the DC-DC converter rail
 + * @new_brownout:     New brownout trigger voltage
 + *
 + * This function configures the output voltage on the DC-DC converter rail.
 + * The rail is selected by the @cfg argument. The new voltage target is
 + * selected by the @new_target and the voltage is specified in mV. The
 + * new brownout value is selected by the @new_brownout argument and the
 + * value is also in mV.
 + */
  static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
                                uint32_t new_target, uint32_t new_brownout)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
-       int adjust_up, tmp;
+       int powered_by_linreg = 0;
+       int adjust_up;
+       if (new_target < cfg->lowest_mV)
+               new_target = cfg->lowest_mV;
+       if (new_target > cfg->highest_mV)
+               new_target = cfg->highest_mV;
  
 -      new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
 +      new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
 +                                       cfg->step_mV);
  
        cur_target = readl(cfg->reg);
        cur_target &= cfg->trg_mask;
  
                if (powered_by_linreg ||
                        (readl(&power_regs->hw_power_sts) &
-                               POWER_STS_VDD5V_GT_VDDIO))
+                               POWER_STS_VDD5V_GT_VDDIO)) {
                        early_delay(500);
-               else {
-                       for (;;) {
-                               tmp = readl(&power_regs->hw_power_sts);
-                               if (tmp & POWER_STS_DC_OK)
-                                       break;
+               } else {
+                       while (!(readl(&power_regs->hw_power_sts) &
+                                       POWER_STS_DC_OK)) {
                        }
                }
  
        }
  }
  
 +/**
 + * mxs_setup_batt_detect() - Start the battery voltage measurement logic
 + *
 + * This function starts and configures the LRADC block. This allows the
 + * power initialization code to measure battery voltage and based on this
 + * knowledge, decide whether to boot at all, boot from battery or boot
 + * from 5V input.
 + */
  static void mxs_setup_batt_detect(void)
  {
        mxs_lradc_init();
        early_delay(10);
  }
  
 +/**
 + * mxs_ungate_power() - Ungate the POWER block
 + *
 + * This function ungates clock to the power block. In case the power block
 + * was still gated at this point, it will not be possible to configure the
 + * block and therefore the power initialization would fail. This function
 + * is only needed on i.MX233, on i.MX28 the power block is always ungated.
 + */
  static void mxs_ungate_power(void)
  {
  #ifdef CONFIG_MX23
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
  #endif
  }
  
+ #ifdef CONFIG_CONFIG_MACH_MX28EVK
+ #define auto_restart 1
+ #else
+ #define auto_restart 0
+ #endif
 +/**
 + * mxs_power_init() - The power block init main function
 + *
 + * This function calls all the power block initialization functions in
 + * proper sequence to start the power block.
 + */
  void mxs_power_init(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        mxs_ungate_power();
  
        mxs_power_clock2xtal();
-       mxs_power_set_auto_restart();
+       if (mxs_power_set_auto_restart(auto_restart)) {
+               serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
+       }
        mxs_power_set_linreg();
-       mxs_power_setup_5v_detect();
  
-       mxs_setup_batt_detect();
+       if (!fixed_batt_supply) {
+               mxs_power_setup_5v_detect();
+               mxs_setup_batt_detect();
+       }
  
        mxs_power_configure_power_source();
        mxs_enable_output_rail_protection();
  
-       mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
-       mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
+       mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
+       mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
+       mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
  #ifdef CONFIG_MX23
-       mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
+       mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
+       setbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
+       early_delay(500);
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_ILIMIT);
+ #else
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
  #endif
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
                POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
                POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-       writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
-       early_delay(1000);
+       if (!fixed_batt_supply)
+               writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+                       &power_regs->hw_power_5vctrl_set);
  }
  
  #ifdef        CONFIG_SPL_MXS_PSWITCH_WAIT
 +/**
 + * mxs_power_wait_pswitch() - Wait for power switch to be pressed
 + *
 + * This function waits until the power-switch was pressed to start booting
 + * the board.
 + */
  void mxs_power_wait_pswitch(void)
  {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
  }
index f2e72257d15b5d77fb7d583152f2b19b1f32a95f,12789327ccb65dbcb18b5b3c5eb66be53dd17a8e..021e21f93928b07fa5b9597fd21fd823f1cfdb59
@@@ -7,7 -7,7 +7,7 @@@
   * Based on code from LTIB:
   * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #include <common.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
- #define timestamp (gd->arch.tbl)
- #define lastdec (gd->arch.lastinc)
+ /* Enable this to verify that the code can correctly
+  * handle the timer rollover
+  */
+ /* #define DEBUG_TIMER_WRAP */
+ #ifdef DEBUG_TIMER_WRAP
+ /*
+  * Let the timer wrap 15 seconds after start to catch misbehaving
+  * timer related code early
+  */
+ #define TIMER_START           (-time_to_tick(15 * CONFIG_SYS_HZ))
+ #else
+ #define TIMER_START           0UL
+ #endif
  
  /*
   * This driver uses 1kHz clock source.
@@@ -42,12 -54,6 +54,6 @@@ static inline unsigned long time_to_tic
        return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
  }
  
- /* Calculate how many ticks happen in "us" microseconds */
- static inline unsigned long us_to_tick(unsigned long us)
- {
-       return (us * MXS_INCREMENTER_HZ) / 1000000;
- }
  int timer_init(void)
  {
        struct mxs_timrot_regs *timrot_regs =
                TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL,
                &timrot_regs->hw_timrot_timctrl0);
  
-       /* Set fixed_count to maximal value */
++#ifndef DEBUG_TIMER_WRAP
+       /* Set fixed_count to maximum value */
  #if defined(CONFIG_MX23)
        writel(TIMER_LOAD_VAL - 1, &timrot_regs->hw_timrot_timcount0);
  #elif defined(CONFIG_MX28)
        writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
  #endif
--
 -#ifndef DEBUG_TIMER_WRAP
 -      /* Set fixed_count to maximum value */
 -      writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
 -#else
++#else /* DEBUG_TIMER_WRAP */
+       /* Set fixed_count so that the counter will wrap after 20 seconds */
++#if defined(CONFIG_MX23)
++      writel(20 * MXS_INCREMENTER_HZ - 1, &timrot_regs->hw_timrot_timcount0);
++#elif defined(CONFIG_MX28)
+       writel(20 * MXS_INCREMENTER_HZ,
+               &timrot_regs->hw_timrot_fixed_count0);
++#endif
+       gd->arch.lastinc = TIMER_LOAD_VAL - 20 * MXS_INCREMENTER_HZ;
+       /* Make the usec counter roll over 30 seconds after startup */
+       writel(-30000000, MXS_HW_DIGCTL_MICROSECONDS);
 -#endif
++#endif /* DEBUG_TIMER_WRAP */
+       writel(TIMROT_TIMCTRLn_UPDATE,
+               &timrot_regs->hw_timrot_timctrl0_clr);
+ #ifdef DEBUG_TIMER_WRAP
 -      /* Set fixed_count to maximal value for subsequent loads */
++      /* Set fixed_count to maximum value for subsequent loads */
++#if defined(CONFIG_MX23)
++      writel(20 * MXS_INCREMENTER_HZ - 1, &timrot_regs->hw_timrot_timcount0);
++#elif defined(CONFIG_MX28)
+       writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+ #endif
++#endif /* DEBUG_TIMER_WRAP */
+       gd->arch.timer_rate_hz = MXS_INCREMENTER_HZ;
+       gd->arch.tbl = TIMER_START;
+       gd->arch.tbu = 0;
        return 0;
  }
  
+ /* Note: This function works correctly for TIMER_LOAD_VAL == 0xffffffff!
+  * The rollover is handled automagically due to the properties of
+  * two's complement arithmetic.
+  * For any other value of TIMER_LOAD_VAL the calculations would have
+  * to be done modulus(TIMER_LOAD_VAL + 1).
+  */
  unsigned long long get_ticks(void)
  {
        struct mxs_timrot_regs *timrot_regs =
                (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
-       uint32_t now;
-       /* Current tick value */
+       unsigned long now;
  #if defined(CONFIG_MX23)
        /* Upper bits are the valid ones. */
        now = readl(&timrot_regs->hw_timrot_timcount0) >>
                TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET;
 -#else
 +#elif defined(CONFIG_MX28)
-       now = readl(&timrot_regs->hw_timrot_running_count0);
+       /* The timer is counting down, so subtract the register value from
+        * the counter period length (implicitly 2^32) to get an incrementing
+        * timestamp
+        */
+       now = -readl(&timrot_regs->hw_timrot_running_count0);
 +#else
 +#error "Don't know how to read timrot_regs"
  #endif
+       ulong inc = now - gd->arch.lastinc;
  
-       if (lastdec >= now) {
-               /*
-                * normal mode (non roll)
-                * move stamp forward with absolut diff ticks
-                */
-               timestamp += (lastdec - now);
-       } else {
-               /* we have rollover of decrementer */
-               timestamp += (TIMER_LOAD_VAL - now) + lastdec;
-       }
-       lastdec = now;
-       return timestamp;
+       if (gd->arch.tbl + inc < gd->arch.tbl)
+               gd->arch.tbu++;
+       gd->arch.tbl += inc;
+       gd->arch.lastinc = now;
+       return ((unsigned long long)gd->arch.tbu << 32) | gd->arch.tbl;
  }
  
  ulong get_timer_masked(void)
  
  ulong get_timer(ulong base)
  {
-       return get_timer_masked() - base;
+       /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
+       return tick_to_time(get_ticks() - time_to_tick(base));
  }
  
  /* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
  
  void __udelay(unsigned long usec)
  {
-       uint32_t old, new, incr;
-       uint32_t counter = 0;
-       old = readl(MXS_HW_DIGCTL_MICROSECONDS);
-       while (counter < usec) {
-               new = readl(MXS_HW_DIGCTL_MICROSECONDS);
-               /* Check if the timer wrapped. */
-               if (new < old) {
-                       incr = 0xffffffff - old;
-                       incr += new;
-               } else {
-                       incr = new - old;
-               }
-               /*
-                * Check if we are close to the maximum time and the counter
-                * would wrap if incremented. If that's the case, break out
-                * from the loop as the requested delay time passed.
+       uint32_t start = readl(MXS_HW_DIGCTL_MICROSECONDS);
+       while (readl(MXS_HW_DIGCTL_MICROSECONDS) - start <= usec)
+               /* use '<=' to guarantee a delay of _at least_
+                * the given number of microseconds.
+                * No need for fancy rollover checks
+                * Two's complement arithmetic applied correctly
+                * does everything that's needed  automagically!
                 */
-               if (counter + incr < counter)
-                       break;
-               counter += incr;
-               old = new;
-       }
+               ;
  }
  
  ulong get_tbclk(void)
  {
-       return MXS_INCREMENTER_HZ;
+       return gd->arch.timer_rate_hz;
  }
index eaf09d1a627746e0aea1c1317aa6a8ea390693ad,032d28c1cb10377c8d8276c5519866ea2aff155c..f5a420378e462f0dd08ede337ea5fedb765d77ad
@@@ -9,9 -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>
  #include <miiphy.h>
  #include <cpsw.h>
  #include <asm/errno.h>
 +#include <linux/compiler.h>
  #include <linux/usb/ch9.h>
  #include <linux/usb/gadget.h>
  #include <linux/usb/musb.h>
  #include <asm/omap_musb.h>
 +#include <asm/davinci_rtc.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
 -static const struct gpio_bank gpio_bank_am33xx[4] = {
 +#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 },
        { (void *)AM33XX_GPIO2_BASE, METHOD_GPIO_24XX },
        { (void *)AM33XX_GPIO3_BASE, METHOD_GPIO_24XX },
 +#ifdef CONFIG_AM43XX
 +      { (void *)AM33XX_GPIO4_BASE, METHOD_GPIO_24XX },
 +      { (void *)AM33XX_GPIO5_BASE, METHOD_GPIO_24XX },
 +#endif
  };
  
  const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
  
 -#ifdef CONFIG_HW_WATCHDOG
 -void hw_watchdog_reset(void)
 -{
 -      struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
 -      static int trg __attribute__((section(".data")));
 -
 -      switch (trg) {
 -      case 0:
 -      case 1:
 -              if (readl(&wdtimer->wdtwwps) & (1 << 4))
 -                      return;
 -              writel(trg ? 0x5555 : 0xaaaa, &wdtimer->wdtwspr);
 -              break;
 -      case 2:
 -              if (readl(&wdtimer->wdtwwps) & (1 << 2))
 -                      return;
 -              /* 10 sec timeout */
 -              writel(-32768 * 10, &wdtimer->wdtwldr);
 -
 -              if (readl(&wdtimer->wdtwwps) & (1 << 0))
 -                      return;
 -              /* prescaler = 1 */
 -              writel(0, &wdtimer->wdtwclr);
 -              break;
 -
 -      case 3:
 -      case 4:
 -              /* enable watchdog */
 -              if (readl(&wdtimer->wdtwwps) & (1 << 4))
 -                      return;
 -              writel((trg & 1) ? 0xBBBB : 0x4444, &wdtimer->wdtwspr);
 -              break;
 -
 -      default:
 -              /* retrigger watchdog */
 -              if (readl(&wdtimer->wdtwwps) & (1 << 3))
 -                      return;
 -
 -              writel(trg, &wdtimer->wdtwtgr);
 -              trg ^= 0x2;
 -              return;
 -      }
 -      trg++;
 -}
 -#endif
 -
 -#ifndef CONFIG_SYS_DCACHE_OFF
 -void enable_caches(void)
 -{
 -      /* Enable D-cache. I-cache is already enabled in start.S */
 -      dcache_enable();
 -}
  #endif
  
  #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
- int cpu_mmc_init(bd_t *bis)
+ int __cpu_mmc_init(bd_t *bis)
  {
        int ret;
  
  
        return omap_mmc_init(1, 0, 0, -1, -1);
  }
+ /* let platform code be able to override this! */
+ int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__cpu_mmc_init")));
  #endif
  
 -void setup_clocks_for_console(void)
 -{
 -      /* Not yet implemented */
 -      return;
 -}
 -
  /* AM33XX has two MUSB controllers which can be host or gadget */
  #if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
        (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
@@@ -203,49 -198,28 +205,49 @@@ int arch_misc_init(void
        return 0;
  }
  
 -#ifdef CONFIG_SPL_BUILD
 -void rtc32k_enable(void)
 +#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 +/*
 + * In the case of non-SPL based booting we'll want to call these
 + * functions a tiny bit later as it will require gd to be set and cleared
 + * and that's not true in s_init in this case so we cannot do it there.
 + */
 +int board_early_init_f(void)
  {
 -      struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
 +      prcm_init();
 +      set_mux_conf_regs();
 +
 +      return 0;
 +}
 +
 +/*
 + * This function is the place to do per-board things such as ramp up the
 + * MPU clock frequency.
 + */
 +__weak void am33xx_spl_board_init(void)
 +{
 +      do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
 +      do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
 +}
 +
 +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
 +static void rtc32k_enable(void)
 +{
 +      struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
  
        /*
         * Unlock the RTC's registers.  For more details please see the
         * RTC_SS section of the TRM.  In order to unlock we need to
         * write these specific values (keys) in this order.
         */
 -      writel(0x83e70b13, &rtc->kick0r);
 -      writel(0x95a4f1e0, &rtc->kick1r);
 +      writel(RTC_KICK0R_WE, &rtc->kick0r);
 +      writel(RTC_KICK1R_WE, &rtc->kick1r);
  
        /* Enable the RTC 32K OSC by setting bits 3 and 6. */
        writel((1 << 3) | (1 << 6), &rtc->osc);
  }
 +#endif
  
 -#define UART_RESET            (0x1 << 1)
 -#define UART_CLK_RUNNING_MASK 0x1
 -#define UART_SMART_IDLE_EN    (0x1 << 0x3)
 -
 -void uart_soft_reset(void)
 +static void uart_soft_reset(void)
  {
        struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
        u32 regval;
        regval |= UART_SMART_IDLE_EN;
        writel(regval, &uart_base->uartsyscfg);
  }
 +
 +static void watchdog_disable(void)
 +{
 +      struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
 +
 +      writel(0xAAAA, &wdtimer->wdtwspr);
 +      while (readl(&wdtimer->wdtwwps) != 0x0)
 +              ;
 +      writel(0x5555, &wdtimer->wdtwspr);
 +      while (readl(&wdtimer->wdtwwps) != 0x0)
 +              ;
 +}
 +
 +void s_init(void)
 +{
 +      /*
 +       * The ROM will only have set up sufficient pinmux to allow for the
 +       * first 4KiB NOR to be read, we must finish doing what we know of
 +       * the NOR mux in this space in order to continue.
 +       */
 +#ifdef CONFIG_NOR_BOOT
 +      enable_norboot_pin_mux();
 +#endif
 +      /*
 +       * Save the boot parameters passed from romcode.
 +       * We cannot delay the saving further than this,
 +       * to prevent overwrites.
 +       */
 +#ifdef CONFIG_SPL_BUILD
 +      save_omap_boot_params();
 +#endif
 +      watchdog_disable();
 +      set_uart_mux_conf();
 +      setup_clocks_for_console();
 +      uart_soft_reset();
 +#if defined(CONFIG_NOR_BOOT) || defined(CONFIG_QSPI_BOOT)
 +      gd->baudrate = CONFIG_BAUDRATE;
 +      serial_init();
 +      gd->have_console = 1;
 +#elif defined(CONFIG_SPL_BUILD)
 +      gd = &gdata;
 +      preloader_console_init();
 +#endif
 +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
 +      /* Enable RTC32K clock */
 +      rtc32k_enable();
 +#endif
 +#ifdef CONFIG_SPL_BUILD
 +      board_early_init_f();
 +      sdram_init();
 +#endif
 +}
  #endif
index 92142c893444bc63ad7e1b811172c5996d6005a0,c05d115735dc978c7b6bc97f08600ef8cc1b5811..23cd9a9fe90dfd14554fa794d4d38db7449c9d04
  #include <asm/arch/hardware.h>
  #include <asm/io.h>
  
 -
+ #define PRCM_MOD_EN           0x2
+ #define PRCM_FORCE_WAKEUP     0x2
+ #define PRCM_FUNCTL           0x0
+ #define PRCM_EMIF_CLK_ACTIVITY        BIT(2)
+ #define PRCM_L3_GCLK_ACTIVITY BIT(4)
+ #define PLL_BYPASS_MODE               0x4
+ #define ST_MN_BYPASS          0x00000100
+ #define ST_DPLL_CLK           0x00000001
+ #define CLK_SEL_MASK          0x7ffff
+ #define CLK_DIV_MASK          0x1f
+ #define CLK_DIV2_MASK         0x7f
+ #define CLK_SEL_SHIFT         0x8
+ #define CLK_MODE_MASK         0x7
+ #define CLK_MODE_SEL          0x7
+ #define DPLL_CLKDCOLDO_GATE_CTRL 0x300
  #define OSC   (V_OSCK/1000000)
  
 -#define MPUPLL_N      (OSC-1)
+ #define MPUPLL_M      CONFIG_SYS_MPUCLK
 -#define COREPLL_N     (OSC-1)
++#define MPUPLL_N      (OSC - 1)
+ #define MPUPLL_M2     1
+ /* Core PLL Fdll = 1 GHZ, */
+ #define COREPLL_M     1000
 -#define PERPLL_N      (OSC-1)
++#define COREPLL_N     (OSC - 1)
+ #define COREPLL_M4    10      /* CORE_CLKOUTM4 = 200 MHZ */
+ #define COREPLL_M5    8       /* CORE_CLKOUTM5 = 250 MHZ */
+ #define COREPLL_M6    4       /* CORE_CLKOUTM6 = 500 MHZ */
+ /*
+  * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
+  * frequency needs to be set to 960 MHZ. Hence,
+  * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
+  */
+ #define PERPLL_M      960
 -#define DDRPLL_N      (OSC-1)
++#define PERPLL_N      (OSC - 1)
+ #define PERPLL_M2     5
+ /* DDR Freq is 266 MHZ for now */
+ /* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
+ #define DDRPLL_M      266
 -const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 -const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 -const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
 -const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
 -
 -#ifdef CONFIG_SPL_BUILD
 -#define enable_clk(reg, val) __enable_clk(#reg, &reg, val)
++#define DDRPLL_N      (OSC - 1)
+ #define DDRPLL_M2     1
 +struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
 +struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;
 +struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
 +struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC;
 +
 +const struct dpll_regs dpll_mpu_regs = {
 +      .cm_clkmode_dpll        = CM_WKUP + 0x88,
 +      .cm_idlest_dpll         = CM_WKUP + 0x20,
 +      .cm_clksel_dpll         = CM_WKUP + 0x2C,
 +      .cm_div_m2_dpll         = CM_WKUP + 0xA8,
 +};
 +
 +const struct dpll_regs dpll_core_regs = {
 +      .cm_clkmode_dpll        = CM_WKUP + 0x90,
 +      .cm_idlest_dpll         = CM_WKUP + 0x5C,
 +      .cm_clksel_dpll         = CM_WKUP + 0x68,
 +      .cm_div_m4_dpll         = CM_WKUP + 0x80,
 +      .cm_div_m5_dpll         = CM_WKUP + 0x84,
 +      .cm_div_m6_dpll         = CM_WKUP + 0xD8,
 +};
 +
 +const struct dpll_regs dpll_per_regs = {
 +      .cm_clkmode_dpll        = CM_WKUP + 0x8C,
 +      .cm_idlest_dpll         = CM_WKUP + 0x70,
 +      .cm_clksel_dpll         = CM_WKUP + 0x9C,
 +      .cm_div_m2_dpll         = CM_WKUP + 0xAC,
 +};
 +
 +const struct dpll_regs dpll_ddr_regs = {
 +      .cm_clkmode_dpll        = CM_WKUP + 0x94,
 +      .cm_idlest_dpll         = CM_WKUP + 0x34,
 +      .cm_clksel_dpll         = CM_WKUP + 0x40,
 +      .cm_div_m2_dpll         = CM_WKUP + 0xA0,
 +};
 +
 +struct dpll_params dpll_mpu_opp100 = {
 +              CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1};
 +const struct dpll_params dpll_core_opp100 = {
 +              1000, OSC-1, -1, -1, 10, 8, 4};
 +const struct dpll_params dpll_mpu = {
 +              MPUPLL_M_300, OSC-1, 1, -1, -1, -1, -1};
 +const struct dpll_params dpll_core = {
 +              50, OSC-1, -1, -1, 1, 1, 1};
 +const struct dpll_params dpll_per = {
 +              960, OSC-1, 5, -1, -1, -1, -1};
 +
 +const struct dpll_params *get_dpll_mpu_params(void)
 +{
 +      return &dpll_mpu;
 +}
  
 -static void __enable_clk(const char *name, const void *reg, u32 mask)
 +const struct dpll_params *get_dpll_core_params(void)
  {
 -      unsigned long timeout = 10000000;
 -
 -      writel(mask, reg);
 -      while (readl(reg) != mask)
 -              /* poor man's timeout, since timers not initialized */
 -              if (timeout-- == 0)
 -                      /* no error message, since console not yet available */
 -                      break;
 +      return &dpll_core;
  }
  
 -static void enable_interface_clocks(void)
 +const struct dpll_params *get_dpll_per_params(void)
  {
 -      /* Enable all the Interconnect Modules */
 -      enable_clk(cmper->l3clkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->l4lsclkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->l4fwclkctrl, PRCM_MOD_EN);
 -      enable_clk(cmwkup->wkl4wkclkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->l3instrclkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->l4hsclkctrl, PRCM_MOD_EN);
 -#ifdef CONFIG_HW_WATCHDOG
 -      enable_clk(cmwkup->wdtimer1ctrl, PRCM_MOD_EN);
 -#endif
 -      /* GPIO0 */
 -      enable_clk(cmwkup->wkgpio0clkctrl, PRCM_MOD_EN);
 +      return &dpll_per;
  }
  
 -/*
 - * Force power domain wake up transition
 - * Ensure that the corresponding interface clock is active before
 - * using the peripheral
 - */
 -static void power_domain_wkup_transition(void)
 +void setup_clocks_for_console(void)
  {
 -      writel(PRCM_FORCE_WAKEUP, &cmper->l3clkstctrl);
 -      writel(PRCM_FORCE_WAKEUP, &cmper->l4lsclkstctrl);
 -      writel(PRCM_FORCE_WAKEUP, &cmwkup->wkclkstctrl);
 -      writel(PRCM_FORCE_WAKEUP, &cmper->l4fwclkstctrl);
 -      writel(PRCM_FORCE_WAKEUP, &cmper->l3sclkstctrl);
 +      clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
 +                      CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
 +                      CD_CLKCTRL_CLKTRCTRL_SHIFT);
 +
 +      clrsetbits_le32(&cmper->l4hsclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
 +                      CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
 +                      CD_CLKCTRL_CLKTRCTRL_SHIFT);
 +
 +      clrsetbits_le32(&cmwkup->wkup_uart0ctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
 +      clrsetbits_le32(&cmper->uart1clkctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
 +      clrsetbits_le32(&cmper->uart2clkctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
 +      clrsetbits_le32(&cmper->uart3clkctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
 +      clrsetbits_le32(&cmper->uart4clkctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
 +      clrsetbits_le32(&cmper->uart5clkctrl,
 +                      MODULE_CLKCTRL_MODULEMODE_MASK,
 +                      MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
 +                      MODULE_CLKCTRL_MODULEMODE_SHIFT);
  }
  
 -/*
 - * Enable the peripheral clock for required peripherals
 - */
 -static void enable_per_clocks(void)
 +void enable_basic_clocks(void)
  {
 -      /* Enable the control module though RBL would have done it*/
 -      enable_clk(cmwkup->wkctrlclkctrl, PRCM_MOD_EN);
 -      /* Enable the timer2 clock */
 -      enable_clk(cmper->timer2clkctrl, PRCM_MOD_EN);
 +      u32 *const clk_domains[] = {
 +              &cmper->l3clkstctrl,
 +              &cmper->l4fwclkstctrl,
 +              &cmper->l3sclkstctrl,
 +              &cmper->l4lsclkstctrl,
 +              &cmwkup->wkclkstctrl,
 +              &cmper->emiffwclkctrl,
 +              &cmrtc->clkstctrl,
 +              0
 +      };
 +
 +      u32 *const clk_modules_explicit_en[] = {
 +              &cmper->l3clkctrl,
 +              &cmper->l4lsclkctrl,
 +              &cmper->l4fwclkctrl,
 +              &cmwkup->wkl4wkclkctrl,
 +              &cmper->l3instrclkctrl,
 +              &cmper->l4hsclkctrl,
 +              &cmwkup->wkgpio0clkctrl,
 +              &cmwkup->wkctrlclkctrl,
 +              &cmper->timer2clkctrl,
 +              &cmper->gpmcclkctrl,
 +              &cmper->elmclkctrl,
 +              &cmper->mmc0clkctrl,
 +              &cmper->mmc1clkctrl,
 +              &cmwkup->wkup_i2c0ctrl,
 +              &cmper->gpio1clkctrl,
 +              &cmper->gpio2clkctrl,
 +              &cmper->gpio3clkctrl,
 +              &cmper->i2c1clkctrl,
 +              &cmper->cpgmac0clkctrl,
 +              &cmper->spi0clkctrl,
 +              &cmrtc->rtcclkctrl,
 +              &cmper->usb0clkctrl,
 +              &cmper->emiffwclkctrl,
 +              &cmper->emifclkctrl,
 +              0
 +      };
 +
 +      do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
 +
        /* Select the Master osc 24 MHZ as Timer2 clock source */
        writel(0x1, &cmdpll->clktimer2clk);
 -
 -#ifdef CONFIG_SYS_NS16550_COM1
 -      /* UART0 */
 -      enable_clk(cmwkup->wkup_uart0ctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_SYS_NS16550_COM2
 -      enable_clk(cmper->uart1clkctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_SYS_NS16550_COM3
 -      enable_clk(cmper->uart2clkctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_SYS_NS16550_COM4
 -      enable_clk(cmper->uart3clkctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_SYS_NS16550_COM5
 -      enable_clk(cmper->uart4clkctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_SYS_NS16550_COM6
 -      enable_clk(cmper->uart5clkctrl, PRCM_MOD_EN);
 -#endif
 -      /* GPMC */
 -      enable_clk(cmper->gpmcclkctrl, PRCM_MOD_EN);
 -
 -      /* ELM */
 -      enable_clk(cmper->elmclkctrl, PRCM_MOD_EN);
 -
 -      /* Ethernet */
 -      enable_clk(cmper->cpswclkstctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->cpgmac0clkctrl, PRCM_MOD_EN);
 -
 -      /* MMC */
 -#ifdef CONFIG_OMAP_MMC_DEV_0
 -      enable_clk(cmper->mmc0clkctrl, PRCM_MOD_EN);
 -#endif
 -#ifdef CONFIG_OMAP_MMC_DEV_1
 -      enable_clk(cmper->mmc1clkctrl, PRCM_MOD_EN);
 -#endif
 -      /* LCD */
 -      enable_clk(cmper->lcdclkctrl, PRCM_MOD_EN);
 -
 -      /* MMC1 */
 -      writel(PRCM_MOD_EN, &cmper->mmc1clkctrl);
 -      while (readl(&cmper->mmc1clkctrl) != PRCM_MOD_EN)
 -              ;
 -
 -      /* i2c0 */
 -      enable_clk(cmwkup->wkup_i2c0ctrl, PRCM_MOD_EN);
 -
 -      /* GPIO1-3 */
 -      enable_clk(cmper->gpio1clkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->gpio2clkctrl, PRCM_MOD_EN);
 -      enable_clk(cmper->gpio3clkctrl, PRCM_MOD_EN);
 -
 -      /* i2c1 */
 -      enable_clk(cmper->i2c1clkctrl, PRCM_MOD_EN);
 -
 -      /* spi0 */
 -      enable_clk(cmper->spi0clkctrl, PRCM_MOD_EN);
 -
 -      /* rtc */
 -      enable_clk(cmrtc->rtcclkctrl, PRCM_MOD_EN);
 -
 -      /* usb0 */
 -      enable_clk(cmper->usb0clkctrl, PRCM_MOD_EN);
  }
 -#endif /* CONFIG_SPL_BUILD */
 -
+ void mpu_pll_config_val(int mpull_m)
+ {
+       u32 clkmode, clksel, div_m2;
+       clkmode = readl(&cmwkup->clkmoddpllmpu);
+       clksel = readl(&cmwkup->clkseldpllmpu);
+       div_m2 = readl(&cmwkup->divm2dpllmpu);
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllmpu);
+       while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
+               ;
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (mpull_m << CLK_SEL_SHIFT) | MPUPLL_N;
+       writel(clksel, &cmwkup->clkseldpllmpu);
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= MPUPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllmpu);
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllmpu);
+       while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK)
+               ;
+ }
+ void mpu_pll_config(void)
+ {
+       mpu_pll_config_val(CONFIG_SYS_MPUCLK);
+ }
+ static void core_pll_config_val(int m)
+ {
+       u32 clkmode, clksel, div_m4, div_m5, div_m6;
+       clkmode = readl(&cmwkup->clkmoddpllcore);
+       clksel = readl(&cmwkup->clkseldpllcore);
+       div_m4 = readl(&cmwkup->divm4dpllcore);
+       div_m5 = readl(&cmwkup->divm5dpllcore);
+       div_m6 = readl(&cmwkup->divm6dpllcore);
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllcore);
+       while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS)
+               ;
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= ((m << CLK_SEL_SHIFT) | COREPLL_N);
+       writel(clksel, &cmwkup->clkseldpllcore);
+       div_m4 &= ~CLK_DIV_MASK;
+       div_m4 |= COREPLL_M4;
+       writel(div_m4, &cmwkup->divm4dpllcore);
+       div_m5 &= ~CLK_DIV_MASK;
+       div_m5 |= COREPLL_M5;
+       writel(div_m5, &cmwkup->divm5dpllcore);
+       div_m6 &= ~CLK_DIV_MASK;
+       div_m6 |= COREPLL_M6;
+       writel(div_m6, &cmwkup->divm6dpllcore);
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllcore);
+       while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK)
+               ;
+ }
+ static inline void core_pll_config(void)
+ {
+       core_pll_config_val(COREPLL_M);
+ }
+ static void per_pll_config_val(int m)
+ {
+       u32 clkmode, clksel, div_m2;
+       clkmode = readl(&cmwkup->clkmoddpllper);
+       clksel = readl(&cmwkup->clkseldpllper);
+       div_m2 = readl(&cmwkup->divm2dpllper);
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllper);
+       while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS)
+               ;
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | PERPLL_N;
+       writel(clksel, &cmwkup->clkseldpllper);
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= PERPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllper);
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllper);
+       while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
+               ;
+       writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
+ }
+ static inline void per_pll_config(void)
+ {
+       per_pll_config_val(PERPLL_M);
+ }
+ static void disp_pll_config_val(int m)
+ {
+       u32 clkmode, clksel, div_m2;
+       clkmode = readl(&cmwkup->clkmoddplldisp);
+       clksel = readl(&cmwkup->clkseldplldisp);
+       div_m2 = readl(&cmwkup->divm2dplldisp);
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddplldisp);
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_MN_BYPASS))
+               ;
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | DISPPLL_N;
+       writel(clksel, &cmwkup->clkseldplldisp);
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= DISPPLL_M2;
+       writel(div_m2, &cmwkup->divm2dplldisp);
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddplldisp);
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_DPLL_CLK))
+               ;
+ }
+ static inline void disp_pll_config(void)
+ {
+       disp_pll_config_val(DISPPLL_M);
+ }
+ void ddr_pll_config(unsigned int ddrpll_m)
+ {
+       u32 clkmode, clksel, div_m2;
+       clkmode = readl(&cmwkup->clkmoddpllddr);
+       clksel = readl(&cmwkup->clkseldpllddr);
+       div_m2 = readl(&cmwkup->divm2dpllddr);
+       /* Set the PLL to bypass Mode */
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= PLL_BYPASS_MODE;
+       writel(clkmode, &cmwkup->clkmoddpllddr);
+       /* Wait till bypass mode is enabled */
+       while (!(readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS))
+               ;
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N;
+       writel(clksel, &cmwkup->clkseldpllddr);
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= DDRPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllddr);
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllddr);
+       /* Wait till dpll is locked */
+       while ((readl(&cmwkup->idlestdpllddr) & ST_DPLL_CLK) != ST_DPLL_CLK)
+               ;
+ }
 -#ifdef CONFIG_SPL_BUILD
 -void enable_emif_clocks(void)
 -{
 -      /* Enable the  EMIF_FW Functional clock */
 -      writel(PRCM_MOD_EN, &cmper->emiffwclkctrl);
 -      /* Enable EMIF0 Clock */
 -      writel(PRCM_MOD_EN, &cmper->emifclkctrl);
 -      /* Poll if module is functional */
 -      while ((readl(&cmper->emifclkctrl)) != PRCM_MOD_EN)
 -              ;
 -}
 -
 -/*
 - * Configure the PLL/PRCM for necessary peripherals
 - */
 -void pll_init()
 -{
 -      mpu_pll_config();
 -      core_pll_config();
 -      per_pll_config();
 -      disp_pll_config();
 -
 -      /* Enable the required interconnect clocks */
 -      enable_interface_clocks();
 -
 -      /* Power domain wake up transition */
 -      power_domain_wkup_transition();
 -
 -      /* Enable the required peripherals */
 -      enable_per_clocks();
 -}
 -#endif
 -
+ #define M(mn) (((mn) & CLK_SEL_MASK) >> CLK_SEL_SHIFT)
+ #define N(mn) ((mn) & CLK_DIV2_MASK)
+ unsigned long __clk_get_rate(u32 m_n, u32 div_m2)
+ {
+       unsigned long rate;
+       div_m2 &= CLK_DIV_MASK;
+       debug("M=%u N=%u M2=%u\n", M(m_n), N(m_n), div_m2);
+       rate = V_OSCK / 1000 * M(m_n) / (N(m_n) + 1) / div_m2;
+       debug("CLK = %lu.%03luMHz\n", rate / 1000, rate % 1000);
+       return rate * 1000;
+ }
+ unsigned long lcdc_clk_rate(void)
+ {
+       return clk_get_rate(cmwkup, disp);
+ }
+ unsigned long mpu_clk_rate(void)
+ {
+       return clk_get_rate(cmwkup, mpu);
+ }
+ enum {
+       CLK_MPU_PLL,
+       CLK_CORE_PLL,
+       CLK_PER_PLL,
+       CLK_DISP_PLL,
+       CLK_GPMC,
+ };
+ static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+ } am33xx_clk_lookup[] = {
+       { "mpu", CLK_MPU_PLL, },
+       { "core", CLK_CORE_PLL, },
+       { "per", CLK_PER_PLL, },
+       { "lcdc", CLK_DISP_PLL, },
+       { "gpmc", CLK_GPMC, },
+ };
+ #define print_pll(dom, pll) {                         \
+       u32 __pll = clk_get_rate(dom, pll);             \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+ #define print_pll2(dom, n, pll) {                     \
+       u32 __m_n = readl(&(dom)->clkseldpll##pll);     \
+       u32 __div = readl(&(dom)->divm##n##dpll##pll);  \
+       u32 __pll = __clk_get_rate(__m_n, __div);       \
+       printf("%-12s %4d.%03d MHz\n", #pll "_m" #n,    \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+ static void do_showclocks(void)
+ {
+       print_pll(cmwkup, mpu);
+       print_pll2(cmwkup, 4, core);
+       print_pll2(cmwkup, 5, core);
+       print_pll2(cmwkup, 6, core);
+       print_pll(cmwkup, ddr);
+       print_pll(cmwkup, per);
+       print_pll(cmwkup, disp);
+ }
+ int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc,
+       char *const argv[])
+ {
+       int i;
+       unsigned long freq;
+       unsigned long __attribute__((unused)) ref = ~0UL;
+       if (argc < 2) {
+               do_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq < 1000) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+               if (strcasecmp(argv[1], am33xx_clk_lookup[i].name) == 0) {
+                       switch (am33xx_clk_lookup[i].index) {
+                       case CLK_MPU_PLL:
+                               mpu_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_CORE_PLL:
+                               core_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_PER_PLL:
+                               per_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_DISP_PLL:
+                               disp_pll_config_val(freq / 1000000);
+                               break;
+                       default:
+                               printf("Cannot change %s clock\n",
+                                       am33xx_clk_lookup[i].name);
+                               return CMD_RET_FAILURE;
+                       }
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               am33xx_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(am33xx_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+                       printf("\t%s\n", am33xx_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
+ }
+ U_BOOT_CMD(
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> Hz"
+ );
index fc66872a3179257cb23d8083672f17a174a7df31,11cbac441cbad8392be45c1413fd8570389b63e5..07a88c2ed43b987ea1bfdc7878fb36eadce4958a
   */
  static struct emif_reg_struct *emif_reg[2] = {
                                (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
-                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
+                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE,
+ };
  
  /**
   * Base addresses for DDR PHY cmd/data regs
   */
  static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
                                (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
-                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2,
+ };
  
  static struct ddr_data_regs *ddr_data_reg[2] = {
                                (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
-                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2,
+ };
  
  /**
   * Base address for ddr io control instances
   */
- static struct ddr_cmdtctrl *ioctrl_reg = {
-                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+ static struct ddr_cmdtctrl *ioctrl_reg =
+                               (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR;
  
-  * Configure EMIF4D5 registers and MR registers
 +static inline u32 get_mr(int nr, u32 cs, u32 mr_addr)
 +{
 +      u32 mr;
 +
 +      mr_addr |= cs << EMIF_REG_CS_SHIFT;
 +      writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
 +
 +      mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data);
 +      debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr);
 +      if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) &&
 +          ((mr & 0x00ff0000) >> 16) == (mr & 0xff) &&
 +          ((mr & 0xff000000) >> 24) == (mr & 0xff))
 +              return mr & 0xff;
 +      else
 +              return mr;
 +}
 +
 +static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val)
 +{
 +      mr_addr |= cs << EMIF_REG_CS_SHIFT;
 +      writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
 +      writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data);
 +}
 +
 +static void configure_mr(int nr, u32 cs)
 +{
 +      u32 mr_addr;
 +
 +      while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK)
 +              ;
 +      set_mr(nr, cs, LPDDR2_MR10, 0x56);
 +
 +      set_mr(nr, cs, LPDDR2_MR1, 0x43);
 +      set_mr(nr, cs, LPDDR2_MR2, 0x2);
 +
 +      mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
 +      set_mr(nr, cs, mr_addr, 0x2);
 +}
 +
 +/*
-       writel(0x1, &emif_reg[nr]->emif_iodft_tlgc);
++ * Configure EMIF4D5 registers and MR registers For details about these magic
++ * values please see the EMIF registers section of the TRM.
 + */
 +void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
 +{
 +      writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl);
 +      writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw);
-       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
-       writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
 +      writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
 +
 +      writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config);
 +      writel(regs->emif_rd_wr_lvl_rmp_win,
 +             &emif_reg[nr]->emif_rd_wr_lvl_rmp_win);
 +      writel(regs->emif_rd_wr_lvl_rmp_ctl,
 +             &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
 +      writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
 +      writel(regs->emif_rd_wr_exec_thresh,
 +             &emif_reg[nr]->emif_rd_wr_exec_thresh);
 +
 +      /*
 +       * for most SOCs these registers won't need to be changed so only
 +       * write to these registers if someone explicitly has set the
 +       * register's value.
 +       */
 +      if(regs->emif_cos_config) {
 +              writel(regs->emif_prio_class_serv_map, &emif_reg[nr]->emif_prio_class_serv_map);
 +              writel(regs->emif_connect_id_serv_1_map, &emif_reg[nr]->emif_connect_id_serv_1_map);
 +              writel(regs->emif_connect_id_serv_2_map, &emif_reg[nr]->emif_connect_id_serv_2_map);
 +              writel(regs->emif_cos_config, &emif_reg[nr]->emif_cos_config);
 +      }
 +
++      /*
++       * Sequence to ensure that the PHY is in a known state prior to
++       * startting hardware leveling.  Also acts as to latch some state from
++       * the EMIF into the PHY.
++       */
++      writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
++      writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
++      writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
++
++      clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
++                      EMIF_REG_INITREF_DIS_MASK);
++
 +      writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
 +      writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
++      writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
++      writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
++
++      /* Perform hardware leveling. */
++      udelay(1000);
++      writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
++             0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
++      writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
++             0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
++
++      writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
++
++      /* Enable read leveling */
++      writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
++
++      /*
++       * Enable full read and write leveling.  Wait for read and write
++       * leveling bit to clear RDWRLVLFULL_START bit 31
++       */
++      while((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) != 0)
++              ;
++
++      /* Check the timeout register to see if leveling is complete */
++      if((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
++              puts("DDR3 H/W leveling incomplete with errors\n");
 +
 +      if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) {
 +              configure_mr(nr, 0);
 +              configure_mr(nr, 1);
 +      }
 +}
 +
  /**
   * Configure SDRAM
   */
  void config_sdram(const struct emif_regs *regs, int nr)
  {
        if (regs->zq_config) {
--              /*
--               * A value of 0x2800 for the REF CTRL will give us
--               * about 570us for a delay, which will be long enough
--               * to configure things.
--               */
--              writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl);
                writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
 -              writel(regs->sdram_config, &cstat->emif_sdram_config);
 +              writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
                writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
                writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
                writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
        }
++      writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
        writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
        writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
--      writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
  }
  
  /**
@@@ -153,67 -75,15 +185,82 @@@ void set_sdram_timings(const struct emi
        writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
  }
  
- void __weak emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
- {
- }
 +/*
-  * Configure EXT PHY registers
++ * Configure EXT PHY registers for hardware leveling
 + */
 +static void ext_phy_settings(const struct emif_regs *regs, int nr)
 +{
-       u32 *ext_phy_ctrl_base = 0;
-       u32 *emif_ext_phy_ctrl_base = 0;
-       const u32 *ext_phy_ctrl_const_regs;
-       u32 i = 0;
-       u32 size;
-       ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1);
-       emif_ext_phy_ctrl_base =
-                       (u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
-       /* Configure external phy control timing registers */
-       for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
-               writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
-               /* Update shadow registers */
-               writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
-       }
 +      /*
-        * external phy 6-24 registers do not change with
-        * ddr frequency
++       * Enable hardware leveling on the EMIF.  For details about these
++       * magic values please see the EMIF registers section of the TRM.
 +       */
-       emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size);
-       if (!size)
-               return;
++      writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
++      writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22_shdw);
++      writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23);
++      writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23_shdw);
++      writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24);
++      writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24_shdw);
++      writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25);
++      writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25_shdw);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26_shdw);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27_shdw);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28_shdw);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29_shdw);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30);
++      writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34_shdw);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35);
++      writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35_shdw);
++      writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
++      writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
 +
-       for (i = 0; i < size; i++) {
-               writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
-               /* Update shadow registers */
-               writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
-       }
++      /*
++       * Sequence to ensure that the PHY is again in a known state after
++       * hardware leveling.
++       */
++      writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
++      writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
++      writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
 +}
 +
  /**
   * Configure DDR PHY
   */
  void config_ddr_phy(const struct emif_regs *regs, int nr)
  {
-        * disable initialization and refreshes for now until we
 +      /*
++       * Disable initialization and refreshes for now until we
 +       * finish programming EMIF regs.
++       * Also set time between rising edge of DDR_RESET to rising
++       * edge of DDR_CKE to > 500us per memory spec.
 +       */
++#ifndef CONFIG_AM43XX
 +      setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
 +                   EMIF_REG_INITREF_DIS_MASK);
++#endif
++      if (regs->zq_config)
++              writel(0x80003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
 +
        writel(regs->emif_ddr_phy_ctlr_1,
                &emif_reg[nr]->emif_ddr_phy_ctrl_1);
        writel(regs->emif_ddr_phy_ctlr_1,
                &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
 +
 +      if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5)
 +              ext_phy_settings(regs, nr);
  }
  
  /**
   */
  void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
  {
 +      if (!cmd)
 +              return;
 +
        writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
 -      writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff);
        writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
  
        writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
 -      writel(cmd->cmd1dldiff, &ddr_cmd_reg[nr]->cm1dldiff);
        writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
  
        writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
 -      writel(cmd->cmd2dldiff, &ddr_cmd_reg[nr]->cm2dldiff);
        writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
  }
  
@@@ -241,9 -111,6 +288,9 @@@ void config_ddr_data(const struct ddr_d
  {
        int i;
  
 +      if (!data)
 +              return;
 +
        for (i = 0; i < DDR_DATA_REGS_NR; i++) {
                writel(data->datardsratio0,
                        &(ddr_data_reg[nr]+i)->dt0rdsratio0);
                        &(ddr_data_reg[nr]+i)->dt0fwsratio0);
                writel(data->datawrsratio0,
                        &(ddr_data_reg[nr]+i)->dt0wrsratio0);
 -              writel(data->datauserank0delay,
 -                      &(ddr_data_reg[nr]+i)->dt0rdelays0);
 -              writel(data->datadldiff0,
 -                      &(ddr_data_reg[nr]+i)->dt0dldiff0);
        }
  }
  
 -void config_io_ctrl(unsigned long val)
 +void config_io_ctrl(const struct ctrl_ioregs *ioregs)
  {
 -      writel(val, &ioctrl_reg->cm0ioctl);
 -      writel(val, &ioctrl_reg->cm1ioctl);
 -      writel(val, &ioctrl_reg->cm2ioctl);
 -      writel(val, &ioctrl_reg->dt0ioctl);
 -      writel(val, &ioctrl_reg->dt1ioctl);
 +      if (!ioregs)
 +              return;
 +
 +      writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl);
 +      writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl);
 +      writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl);
 +      writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl);
 +      writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl);
 +#ifdef CONFIG_AM43XX
 +      writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl);
 +      writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl);
 +      writel(ioregs->emif_sdram_config_ext,
 +             &ioctrl_reg->emif_sdram_config_ext);
 +#endif
  }
index 781d83fc72a400f416d7c23b8f3f32b4b924af3a,ab327c86566653194f42ea9c2c33d95e8d7e67ac..9d18aaac441810ee746f41b146414e7516390867
@@@ -17,8 -17,6 +17,8 @@@
  #include <asm/arch/sys_proto.h>
  #include <asm/arch/cpu.h>
  #include <asm/arch/clock.h>
 +#include <power/tps65910.h>
 +#include <linux/compiler.h>
  
  struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
  
@@@ -52,11 -50,11 +52,11 @@@ u32 get_cpu_type(void
  
  /**
   * get_board_rev() - setup to pass kernel board revision information
 - * returns:(bit[0-3] sub version, higher bit[7-4] is higher version)
 + * returns: 0 for the ATAG REVISION tag value.
   */
 -u32 get_board_rev(void)
 +u32 __weak get_board_rev(void)
  {
 -      return BOARD_REV_ID;
 +      return 0;
  }
  
  /**
@@@ -65,7 -63,7 +65,7 @@@
  u32 get_device_type(void)
  {
        int mode;
-       mode = readl(&cstat->statusreg) & (DEVICE_MASK);
+       mode = readl(&cstat->statusreg) & DEVICE_MASK;
        return mode >>= 8;
  }
  
  u32 get_sysboot_value(void)
  {
        int mode;
-       mode = readl(&cstat->statusreg) & (SYSBOOT_MASK);
+       mode = readl(&cstat->statusreg) & SYSBOOT_MASK;
        return mode;
  }
  
  #ifdef CONFIG_DISPLAY_CPUINFO
  static char *cpu_revs[] = {
-               "1.0",
-               "2.0",
-               "2.1"};
+       "1.0",
+       "2.0",
+       "2.1",
+ };
  
  static char *dev_types[] = {
-               "TST",
-               "EMU",
-               "HS",
-               "GP"};
+       "TST",
+       "EMU",
+       "HS",
+       "GP",
+ };
  
  /**
   * Print CPU information
@@@ -108,7 -107,6 +109,6 @@@ int print_cpuinfo(void
                break;
        default:
                cpu_s = "Unknown CPU type";
-               break;
        }
  
        if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
        return 0;
  }
  #endif        /* CONFIG_DISPLAY_CPUINFO */
 +
 +#ifdef CONFIG_AM33XX
 +int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev)
 +{
 +      int sil_rev;
 +
 +      sil_rev = readl(&cdev->deviceid) >> 28;
 +
 +      if (sil_rev == 1)
 +              /* PG 2.0, efuse may not be set. */
 +              return MPUPLL_M_800;
 +      else if (sil_rev >= 2) {
 +              /* Check what the efuse says our max speed is. */
 +              int efuse_arm_mpu_max_freq;
 +              efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
 +              switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) {
 +              case AM335X_ZCZ_1000:
 +                      return MPUPLL_M_1000;
 +              case AM335X_ZCZ_800:
 +                      return MPUPLL_M_800;
 +              case AM335X_ZCZ_720:
 +                      return MPUPLL_M_720;
 +              case AM335X_ZCZ_600:
 +              case AM335X_ZCE_600:
 +                      return MPUPLL_M_600;
 +              case AM335X_ZCZ_300:
 +              case AM335X_ZCE_300:
 +                      return MPUPLL_M_300;
 +              }
 +      }
 +
 +      /* PG 1.0 or otherwise unknown, use the PG1.0 max */
 +      return MPUPLL_M_720;
 +}
 +
 +int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
 +{
 +      /* For PG2.1 and later, we have one set of values. */
 +      if (sil_rev >= 2) {
 +              switch (frequency) {
 +              case MPUPLL_M_1000:
 +                      return TPS65910_OP_REG_SEL_1_3_2_5;
 +              case MPUPLL_M_800:
 +                      return TPS65910_OP_REG_SEL_1_2_6;
 +              case MPUPLL_M_720:
 +                      return TPS65910_OP_REG_SEL_1_2_0;
 +              case MPUPLL_M_600:
 +              case MPUPLL_M_300:
 +                      return TPS65910_OP_REG_SEL_1_1_3;
 +              }
 +      }
 +
 +      /* Default to PG1.0/PG2.0 values. */
 +      return TPS65910_OP_REG_SEL_1_1_3;
 +}
 +#endif
index 0f9d8377ed5ac568d996257647c9137d6fa60477,f7865bc389c44d893f4d24137dcb1e25812ecb45..8ebe9b0303c9916adbfbc3c08094c38a7b49a196
@@@ -21,8 -21,7 +21,8 @@@
   * to get size details from Current Cache Size ID Register(CCSIDR)
   */
  static void set_csselr(u32 level, u32 type)
 -{     u32 csselr = level << 1 | type;
 +{
 +      u32 csselr = level << 1 | type;
  
        /* Write to Cache Size Selection Register(CSSELR) */
        asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr));
@@@ -50,8 -49,7 +50,8 @@@ static void v7_inval_dcache_level_setwa
                                         u32 num_ways, u32 way_shift,
                                         u32 log2_line_len)
  {
 -      int way, set, setway;
 +      int way, set;
 +      u32 setway;
  
        /*
         * For optimal assembly code:
@@@ -75,8 -73,7 +75,8 @@@ static void v7_clean_inval_dcache_level
                                               u32 num_ways, u32 way_shift,
                                               u32 log2_line_len)
  {
 -      int way, set, setway;
 +      int way, set;
 +      u32 setway;
  
        /*
         * For optimal assembly code:
@@@ -137,6 -134,7 +137,6 @@@ static void v7_maint_dcache_level_setwa
  static void v7_maint_dcache_all(u32 operation)
  {
        u32 level, cache_type, level_start_bit = 0;
 -
        u32 clidr = get_clidr();
  
        for (level = 0; level < 7; level++) {
        }
  }
  
 -static void v7_dcache_clean_inval_range(u32 start,
 -                                      u32 stop, u32 line_len)
 +static void v7_dcache_clean_inval_range(u32 start, u32 stop, u32 line_len)
  {
        u32 mva;
  
@@@ -221,16 -220,18 +221,18 @@@ static void v7_dcache_maint_range(u32 s
  /* Invalidate TLB */
  static void v7_inval_tlb(void)
  {
-       /* Invalidate entire unified TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
-       /* Invalidate entire data TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
-       /* Invalidate entire instruction TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-       /* Full system ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               /* Invalidate entire unified TLB */
+               "mcr p15, 0, %0, c8, c7, 0\n"
+               /* Invalidate entire data TLB */
+               "mcr p15, 0, %0, c8, c6, 0\n"
+               /* Invalidate entire instruction TLB */
+               "mcr p15, 0, %0, c8, c5, 0\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* Full system ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
  }
  
  void invalidate_dcache_all(void)
@@@ -257,6 -258,7 +259,6 @@@ void flush_dcache_all(void
   */
  void invalidate_dcache_range(unsigned long start, unsigned long stop)
  {
 -
        v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE);
  
        v7_outer_cache_inval_range(start, stop);
@@@ -337,16 -339,15 +339,15 @@@ void invalidate_icache_all(void
         * Invalidate all instruction caches to PoU.
         * Also flushes branch target cache.
         */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
-       /* Invalidate entire branch predictor array */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-       /* ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               "mcr p15, 0, %0, c7, c5, 0\n"
+               /* Invalidate entire branch predictor array */
+               "mcr p15, 0, %0, c7, c5, 6\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
  }
  #else
  void invalidate_icache_all(void)
  }
  #endif
  
 -/*
 - * Stub implementations for outer cache operations
 - */
 -void __v7_outer_cache_enable(void)
 -{
 -}
 -void v7_outer_cache_enable(void)
 -      __attribute__((weak, alias("__v7_outer_cache_enable")));
 -
 -void __v7_outer_cache_disable(void)
 -{
 -}
 -void v7_outer_cache_disable(void)
 -      __attribute__((weak, alias("__v7_outer_cache_disable")));
 -
 -void __v7_outer_cache_flush_all(void)
 -{
 -}
 -void v7_outer_cache_flush_all(void)
 -      __attribute__((weak, alias("__v7_outer_cache_flush_all")));
 -
 -void __v7_outer_cache_inval_all(void)
 -{
 -}
 -void v7_outer_cache_inval_all(void)
 -      __attribute__((weak, alias("__v7_outer_cache_inval_all")));
 -
 -void __v7_outer_cache_flush_range(u32 start, u32 end)
 -{
 -}
 -void v7_outer_cache_flush_range(u32 start, u32 end)
 -      __attribute__((weak, alias("__v7_outer_cache_flush_range")));
 -
 -void __v7_outer_cache_inval_range(u32 start, u32 end)
 -{
 -}
 -void v7_outer_cache_inval_range(u32 start, u32 end)
 -      __attribute__((weak, alias("__v7_outer_cache_inval_range")));
 +/*  Stub implementations for outer cache operations */
 +__weak void v7_outer_cache_enable(void) {}
 +__weak void v7_outer_cache_disable(void) {}
 +__weak void v7_outer_cache_flush_all(void) {}
 +__weak void v7_outer_cache_inval_all(void) {}
 +__weak void v7_outer_cache_flush_range(u32 start, u32 end) {}
 +__weak void v7_outer_cache_inval_range(u32 start, u32 end) {}
index f1aea05c9094677c8e7c6bf8126d8d4ab970ba30,cf477a978f56fc2fb0a72359665799984bc11648..d71c84fae5b85adcd7d170542728973a1e87e734
@@@ -19,14 -19,18 +19,18 @@@ ENTRY(lowlevel_init
        /*
         * Setup a temporary stack
         */
+ #ifndef CONFIG_SPL_BUILD
        ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
+ #else
+       ldr     sp, =CONFIG_SPL_STACK
+ #endif
        bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
  #ifdef CONFIG_SPL_BUILD
 -      ldr     r8, =gdata
 +      ldr     r9, =gdata
  #else
 -      sub     sp, #GD_SIZE
 +      sub     sp, sp, #GD_SIZE
        bic     sp, sp, #7
 -      mov     r8, sp
 +      mov     r9, sp
  #endif
        /*
         * Save the old lr(passed in ip) and the current lr to stack
index bf52f0d19e546e0b98b2717b25618c4c6711e92b,fe2f86f2d834f8ce3cde9cd0fc116195575b968c..443fb997826244080a4dd3d4ce7a1a979ee1e802
@@@ -46,15 -46,14 +46,14 @@@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS
  #define EMI_DIV_MAX     8
  #define NFC_DIV_MAX     8
  
- #define MX5_CBCMR     0x00015154
- #define MX5_CBCDR     0x02888945
+ #define MXC_IPG_PER_CLK       MXC_IPG_PERCLK
  
  struct fixed_pll_mfd {
        u32 ref_clk_hz;
        u32 mfd;
  };
  
- const struct fixed_pll_mfd fixed_mfd[] = {
static const struct fixed_pll_mfd fixed_mfd[] = {
        {MXC_HCLK, 24 * 16},
  };
  
@@@ -67,12 -66,102 +66,102 @@@ struct pll_param 
  
  #define PLL_FREQ_MAX(ref_clk)  (4 * (ref_clk) * PLL_MFI_MAX)
  #define PLL_FREQ_MIN(ref_clk) \
-               ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
+       ((4 * (ref_clk) * PLL_MFI_MIN) / PLL_PD_MAX)
  #define MAX_DDR_CLK     420000000
  #define NFC_CLK_MAX     34000000
  
  struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
  
+ int clk_enable(struct clk *clk)
+ {
+       int ret = 0;
+       if (!clk)
+               return 0;
+       if (clk->usecount++ == 0) {
+               if (!clk->enable)
+                       return 0;
+               ret = clk->enable(clk);
+               if (ret)
+                       clk->usecount--;
+       }
+       return ret;
+ }
+ void clk_disable(struct clk *clk)
+ {
+       if (!clk)
+               return;
+       if (!(--clk->usecount)) {
+               if (clk->disable)
+                       clk->disable(clk);
+       }
+       if (clk->usecount < 0) {
+               printf("%s: clk %p (%s) underflow\n", __func__, clk, clk->name);
+               hang();
+       }
+ }
+ int clk_get_usecount(struct clk *clk)
+ {
+       if (clk == NULL)
+               return 0;
+       return clk->usecount;
+ }
+ u32 clk_get_rate(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk->rate;
+ }
+ struct clk *clk_get_parent(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk->parent;
+ }
+ int clk_set_rate(struct clk *clk, unsigned long rate)
+ {
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+ }
+ long clk_round_rate(struct clk *clk, unsigned long rate)
+ {
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+       return clk->round_rate(clk, rate);
+ }
+ int clk_set_parent(struct clk *clk, struct clk *parent)
+ {
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+       if (!clk || clk == parent)
+               return 0;
+       if (clk->set_parent) {
+               int ret;
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+ }
  void set_usboh3_clk(void)
  {
        clrsetbits_le32(&mxc_ccm->cscmr1,
                        MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1));
  }
  
 -void enable_usboh3_clk(unsigned char enable)
 +void enable_usboh3_clk(bool enable)
  {
        unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
                        MXC_CCM_CCGR2_USBOH3_60M(cg));
  }
  
 -#ifdef CONFIG_I2C_MXC
+ void ipu_clk_enable(void)
+ {
+       /* IPU root clock derived from AXI B */
+       clrsetbits_le32(&mxc_ccm->cbcmr, MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK,
+                       MXC_CCM_CBCMR_IPU_HSP_CLK_SEL(1));
+       setbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+       /* Handshake with IPU when certain clock rates are changed. */
+       clrbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       clrbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+ }
+ void ipu_clk_disable(void)
+ {
+       clrbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+       /* Handshake with IPU when certain clock rates are changed. */
+       setbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       setbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+ }
+ void ipu_di_clk_enable(int di)
+ {
+       switch (di) {
+       case 0:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+ }
+ void ipu_di_clk_disable(int di)
+ {
+       switch (di) {
+       case 0:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+ }
+ #ifdef CONFIG_MX53
+ void ldb_clk_enable(int ldb)
+ {
+       switch (ldb) {
+       case 0:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+ }
+ void ldb_clk_disable(int ldb)
+ {
+       switch (ldb) {
+       case 0:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+ }
+ #endif
 +#ifdef CONFIG_SYS_I2C_MXC
  /* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */
  int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  {
@@@ -122,7 -305,7 +305,7 @@@ void set_usb_phy_clk(void
  }
  
  #if defined(CONFIG_MX51)
 -void enable_usb_phy1_clk(unsigned char enable)
 +void enable_usb_phy1_clk(bool enable)
  {
        unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
                        MXC_CCM_CCGR2_USB_PHY(cg));
  }
  
 -void enable_usb_phy2_clk(unsigned char enable)
 +void enable_usb_phy2_clk(bool enable)
  {
        /* i.MX51 has a single USB PHY clock, so do nothing here. */
  }
  #elif defined(CONFIG_MX53)
 -void enable_usb_phy1_clk(unsigned char enable)
 +void enable_usb_phy1_clk(bool enable)
  {
        unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
                        MXC_CCM_CCGR4_USB_PHY1(cg));
  }
  
 -void enable_usb_phy2_clk(unsigned char enable)
 +void enable_usb_phy2_clk(bool enable)
  {
        unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF;
  
   */
  static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq)
  {
-       uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret;
+       uint32_t ctrl, op;
+       int mfd, mfn, mfi, pdf, ret;
        uint64_t refclk, temp;
-       int32_t mfn_abs;
+       uint32_t mfn_abs;
  
        ctrl = readl(&pll->ctrl);
  
        if (mfn >= 0x04000000) {
                mfn |= 0xfc000000;
                mfn_abs = -mfn;
-       } else
+       } else {
                mfn_abs = mfn;
+       }
        refclk = infreq * 2;
        if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN)
                refclk *= 2;
  
-       do_div(refclk, pdf + 1);
        temp = refclk * mfn_abs;
        do_div(temp, mfd + 1);
        ret = refclk * mfi;
  
-       if ((int)mfn < 0)
+       if (mfn < 0)
                ret -= temp;
        else
                ret += temp;
  
+       ret /= pdf + 1;
        return ret;
  }
  
@@@ -444,6 -628,17 +628,17 @@@ static u32 get_emi_slow_clk(void
        return  get_periph_clk() / (pdf + 1);
  }
  
+ static u32 get_nfc_clk(void)
+ {
+       u32 parent_rate = get_emi_slow_clk();
+       u32 div = readl(&mxc_ccm->cbcdr);
+       div &= MXC_CCM_CBCDR_NFC_PODF_MASK;
+       div >>= MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+       div++;
+       return parent_rate / div;
+ }
  static u32 get_ddr_clk(void)
  {
        u32 ret_val = 0;
@@@ -513,6 -708,14 +708,14 @@@ unsigned int mxc_get_clock(enum mxc_clo
                return get_ahb_clk();
        case MXC_DDR_CLK:
                return get_ddr_clk();
+       case MXC_AXI_A_CLK:
+               return get_axi_a_clk();
+       case MXC_AXI_B_CLK:
+               return get_axi_b_clk();
+       case MXC_EMI_SLOW_CLK:
+               return get_emi_slow_clk();
+       case MXC_NFC_CLK:
+               return get_nfc_clk();
        default:
                break;
        }
@@@ -551,18 -754,17 +754,17 @@@ static int gcd(int m, int n
   */
  static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
  {
-       u64 pd, mfi = 1, mfn, mfd, t1;
-       u32 n_target = target;
-       u32 n_ref = ref, i;
+       int pd, mfi = 1, mfn, mfd;
+       u64 t1;
+       size_t i;
  
        /*
         * Make sure targeted freq is in the valid range.
         * Otherwise the following calculation might be wrong!!!
         */
-       if (n_target < PLL_FREQ_MIN(ref) ||
-               n_target > PLL_FREQ_MAX(ref)) {
-               printf("Targeted peripheral clock should be"
-                       "within [%d - %d]\n",
+       if (target < PLL_FREQ_MIN(ref) ||
+               target > PLL_FREQ_MAX(ref)) {
+               printf("Targeted pll clock should be within [%d - %d]\n",
                        PLL_FREQ_MIN(ref) / SZ_DEC_1M,
                        PLL_FREQ_MAX(ref) / SZ_DEC_1M);
                return -EINVAL;
        if (i == ARRAY_SIZE(fixed_mfd))
                return -EINVAL;
  
-       /* Use n_target and n_ref to avoid overflow */
        for (pd = 1; pd <= PLL_PD_MAX; pd++) {
-               t1 = n_target * pd;
-               do_div(t1, (4 * n_ref));
+               t1 = (u64)target * pd;
+               do_div(t1, (4 * ref));
                mfi = t1;
                if (mfi > PLL_MFI_MAX)
                        return -EINVAL;
        /*
         * Now got pd and mfi already
         *
-        * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
+        * mfn = (((target * pd) / 4 - ref * mfi) * mfd) / ref;
         */
-       t1 = n_target * pd;
+       t1 = (u64)target * pd;
        do_div(t1, 4);
-       t1 -= n_ref * mfi;
-       t1 *= mfd;
-       do_div(t1, n_ref);
+       t1 = (t1 - ref * mfi) * mfd;
+       do_div(t1, ref);
        mfn = t1;
-       debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n",
-               ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
-       i = 1;
-       if (mfn != 0)
+       if (mfn != 0) {
                i = gcd(mfd, mfn);
-       pll->pd = (u32)pd;
-       pll->mfi = (u32)mfi;
-       do_div(mfn, i);
-       pll->mfn = (u32)mfn;
-       do_div(mfd, i);
-       pll->mfd = (u32)mfd;
+               mfn /= i;
+               mfd /= i;
+       } else {
+               mfd = 1;
+       }
+       debug("ref=%d, target=%d, pd=%d, mfi=%d, mfn=%d, mfd=%d\n",
+               ref, target, pd, mfi, mfn, mfd);
+       pll->pd = pd;
+       pll->mfi = mfi;
+       pll->mfn = mfn;
+       pll->mfd = mfd;
  
        return 0;
  }
  
  #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
        {       \
-               writel(0x1232, &pll->ctrl);             \
-               writel(0x2, &pll->config);              \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->op);                      \
-               writel(fn, &(pll->mfn));                \
-               writel((fd) - 1, &pll->mfd);            \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->hfs_op);                  \
-               writel(fn, &pll->hfs_mfn);              \
-               writel((fd) - 1, &pll->hfs_mfd);        \
-               writel(0x1232, &pll->ctrl);             \
-               while (!readl(&pll->ctrl) & 0x1)        \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               __raw_writel(0x2, &pll->config);                \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->op);                              \
+               __raw_writel(fn, &(pll->mfn));                  \
+               __raw_writel((fd) - 1, &pll->mfd);              \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->hfs_op);                          \
+               __raw_writel(fn, &pll->hfs_mfn);                \
+               __raw_writel((fd) - 1, &pll->hfs_mfd);          \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               while (!__raw_readl(&pll->ctrl) & 0x1)          \
                        ;\
        }
  
  static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
  {
-       u32 ccsr = readl(&mxc_ccm->ccsr);
+       u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
        struct mxc_pll_reg *pll = mxc_plls[index];
  
        switch (index) {
        case PLL1_CLOCK:
                /* Switch ARM to PLL2 clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x4, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr);
                break;
        case PLL2_CLOCK:
                /* Switch to pll2 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x2, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr);
                break;
        case PLL3_CLOCK:
                /* Switch to pll3 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x1, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
                break;
  #ifdef CONFIG_MX53
        case PLL4_CLOCK:
                /* Switch to pll4 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x20, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
                break;
  #endif
        default:
        return 0;
  }
  
+ static int __adjust_core_voltage_stub(u32 freq)
+ {
+       return 0;
+ }
+ int adjust_core_voltage(u32 freq)
+       __attribute__((weak, alias("__adjust_core_voltage_stub")));
  /* Config CPU clock */
  static int config_core_clk(u32 ref, u32 freq)
  {
        int ret = 0;
        struct pll_param pll_param;
+       u32 cur_freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
+       if (freq == cur_freq)
+               return 0;
  
        memset(&pll_param, 0, sizeof(struct pll_param));
  
        /* The case that periph uses PLL1 is not considered here */
        ret = calc_pll_params(ref, freq, &pll_param);
        if (ret != 0) {
-               printf("Error:Can't find pll parameters: %d\n", ret);
+               printf("Error: Can't find pll parameters for %u.%03uMHz ref %u.%03uMHz\n",
+                       freq / 1000000, freq / 1000 % 1000,
+                       ref / 1000000, ref / 1000 % 1000);
                return ret;
        }
-       return config_pll_clk(PLL1_CLOCK, &pll_param);
+       if (freq > cur_freq) {
+               ret = adjust_core_voltage(freq);
+               if (ret < 0) {
+                       printf("Failed to adjust core voltage for changing ARM clk from %u.%03uMHz to  %u.%03uMHz\n",
+                               cur_freq / 1000000, cur_freq / 1000 % 1000,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return ret;
+               }
+               ret = config_pll_clk(PLL1_CLOCK, &pll_param);
+               if (ret) {
+                       adjust_core_voltage(cur_freq);
+               }
+       } else {
+               ret = config_pll_clk(PLL1_CLOCK, &pll_param);
+               if (ret) {
+                       return ret;
+               }
+               ret = adjust_core_voltage(freq);
+               if (ret < 0) {
+                       printf("Failed to adjust core voltage for changing ARM clk from %u.%03uMHz to  %u.%03uMHz\n",
+                               cur_freq / 1000000, cur_freq / 1000 % 1000,
+                               freq / 1000000, freq / 1000 % 1000);
+                       calc_pll_params(ref, cur_freq, &pll_param);
+                       config_pll_clk(PLL1_CLOCK, &pll_param);
+               }
+       }
+       return ret;
  }
  
  static int config_nfc_clk(u32 nfc_clk)
@@@ -749,18 -981,6 +981,18 @@@ void enable_nfc_clk(unsigned char enabl
                MXC_CCM_CCGR5_EMI_ENFC(cg));
  }
  
 +#ifdef CONFIG_FSL_IIM
 +void enable_efuse_prog_supply(bool enable)
 +{
 +      if (enable)
 +              setbits_le32(&mxc_ccm->cgpr,
 +                           MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE);
 +      else
 +              clrbits_le32(&mxc_ccm->cgpr,
 +                           MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE);
 +}
 +#endif
 +
  /* Config main_bus_clock for periphs */
  static int config_periph_clk(u32 ref, u32 freq)
  {
@@@ -914,36 -1134,118 +1146,118 @@@ void mxc_set_sata_internal_clock(void
  /*
   * Dump some core clockes.
   */
- int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ #define pr_clk_val(c, v) {                                    \
+       printf("%-11s %3lu.%03lu MHz\n", #c,                    \
+               (v) / 1000000, (v) / 1000 % 1000);              \
+ }
+ #define pr_clk(c) {                                           \
+       unsigned long __clk = mxc_get_clock(MXC_##c##_CLK);     \
+       pr_clk_val(c, __clk);                                   \
+ }
+ static int do_mx5_showclocks(void)
  {
-       u32 freq;
+       unsigned long freq;
  
        freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
-       printf("PLL1       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL1, freq);
        freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
-       printf("PLL2       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL2, freq);
        freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
-       printf("PLL3       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL3, freq);
  #ifdef        CONFIG_MX53
        freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK);
-       printf("PLL4       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL4, freq);
  #endif
  
        printf("\n");
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
+       pr_clk(AHB);
+       pr_clk(AXI_A);
+       pr_clk(AXI_B);
+       pr_clk(IPG);
+       pr_clk(IPG_PER);
+       pr_clk(DDR);
+       pr_clk(EMI_SLOW);
+       pr_clk(NFC);
  #ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
+       pr_clk(CSPI);
  #endif
        return 0;
  }
  
+ static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+ } mx5_clk_lookup[] = {
+       { "arm", MXC_ARM_CLK, },
+ };
+ int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int i;
+       unsigned long freq;
+       unsigned long ref = ~0UL;
+       if (argc < 2) {
+               do_mx5_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq == 0) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(mx5_clk_lookup); i++) {
+               if (strcasecmp(argv[1], mx5_clk_lookup[i].name) == 0) {
+                       switch (mx5_clk_lookup[i].index) {
+                       case MXC_ARM_CLK:
+                               if (argc > 3)
+                                       return CMD_RET_USAGE;
+                               ref = CONFIG_SYS_MX5_HCLK;
+                               break;
+                       case MXC_NFC_CLK:
+                               if (argc > 3 && ref > 3) {
+                                       printf("Invalid clock selector value: %lu\n", ref);
+                                       return CMD_RET_FAILURE;
+                               }
+                               break;
+                       }
+                       printf("Setting %s clock to %lu MHz\n",
+                               mx5_clk_lookup[i].name, freq);
+                       if (mxc_set_clock(ref, freq, mx5_clk_lookup[i].index))
+                               break;
+                       freq = mxc_get_clock(mx5_clk_lookup[i].index);
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               mx5_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(mx5_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(mx5_clk_lookup); i++) {
+                       printf("\t%s\n", mx5_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
+ }
  /***************************************************/
  
  U_BOOT_CMD(
-       clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks,
-       "display clocks",
-       ""
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
  );
index f5bc6728b7c2ce4cbe4bcbdef260b39d1cfc1e32,d6edb3f15530ef672cb32c5dc4f792f0f659e72f..3e7746b9bfde65b1f81ad995c446007e66c47e89
  
        /* reconfigure L2 cache aux control reg */
        ldr r0, =0xC0 |                 /* tag RAM */ \
 -               0x4 |                  /* data RAM */ \
 -               1 << 24 |              /* disable write allocate delay */ \
 -               1 << 23 |              /* disable write allocate combine */ \
 -               1 << 22                /* disable write allocate */
 +               0x4 |                  /* data RAM */ \
 +               1 << 24 |              /* disable write allocate delay */ \
 +               1 << 23 |              /* disable write allocate combine */ \
 +               1 << 22                /* disable write allocate */
  
  #if defined(CONFIG_MX51)
        ldr r3, [r4, #ROM_SI_REV]
  #endif
  
        mcr 15, 1, r0, c9, c0, 2
 +
 +      /* enable L2 cache */
 +      mrc 15, 0, r0, c1, c0, 1
 +      orr r0, r0, #2
 +      mcr 15, 0, r0, c1, c0, 1
 +
  .endm /* init_l2cc */
  
  /* AIPS setup - Only setup MPROTx registers.
@@@ -97,7 -91,7 +97,7 @@@
  .endm /* init_m4if */
  
  .macro setup_pll pll, freq
-       ldr r0, =\pll
+       ldr r3, =\pll
        adr r2, W_DP_\freq
        bl setup_pll_func
  .endm
  
  setup_pll_func:
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
+       str r1, [r3, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
        mov r1, #0x2
-       str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
+       str r1, [r3, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
  
        ldr r1, [r2, #W_DP_OP]
-       str r1, [r0, #PLL_DP_OP]
-       str r1, [r0, #PLL_DP_HFS_OP]
+       str r1, [r3, #PLL_DP_OP]
+       str r1, [r3, #PLL_DP_HFS_OP]
  
        ldr r1, [r2, #W_DP_MFD]
-       str r1, [r0, #PLL_DP_MFD]
-       str r1, [r0, #PLL_DP_HFS_MFD]
+       str r1, [r3, #PLL_DP_MFD]
+       str r1, [r3, #PLL_DP_HFS_MFD]
  
        ldr r1, [r2, #W_DP_MFN]
-       str r1, [r0, #PLL_DP_MFN]
-       str r1, [r0, #PLL_DP_HFS_MFN]
+       str r1, [r3, #PLL_DP_MFN]
+       str r1, [r3, #PLL_DP_HFS_MFN]
  
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL]
- 1:    ldr r1, [r0, #PLL_DP_CTL]
+       str r1, [r3, #PLL_DP_CTL]
+ 1:    ldr r1, [r3, #PLL_DP_CTL]
        ands r1, r1, #0x1
        beq 1b
  
  .endm
  
  .macro init_clock
- #if defined (CONFIG_MX51)
        ldr r0, =CCM_BASE_ADDR
-       /* Gate of clocks to the peripherals first */
+ #if defined (CONFIG_MX51)
+       /* Gate off clocks to the peripherals first */
        ldr r1, =0x3FFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
        str r4, [r0, #CLKCTL_CCGR1]
        str r1, [r0, #CLKCTL_CBCDR]
        /* make sure divider effective */
  1:    ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
  
        /* Switch ARM to step clock */
        setup_pll PLL1_BASE_ADDR, 864
        setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT
  #else
+ #if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
+ #elif CONFIG_SYS_CPU_CLK == 600
+       setup_pll PLL1_BASE_ADDR, 600
+ #else
+ #error Unsupported CONFIG_SYS_CPU_CLK value
+ #endif
  #endif
  
        setup_pll PLL3_BASE_ADDR, 665
  
        /* Switch peripheral to PLL 3 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x000010C0 | CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CBCMR]
        ldr r1, =0x13239145
        setup_pll PLL2_BASE_ADDR, 665
  
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x19239145
        str r1, [r0, #CLKCTL_CBCDR]
        ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CSCDR1]
        /* make sure divider effective */
  1:    ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
  
        str r4, [r0, #CLKCTL_CCDR]
        add r1, r1, #0x00000F0
        str r1, [r0, #CLKCTL_CCOSR]
  #else /* CONFIG_MX53 */
-       ldr r0, =CCM_BASE_ADDR
-       /* Gate of clocks to the peripherals first */
+       /* Gate off clocks to the peripherals first */
        ldr r1, =0x3FFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
        str r4, [r0, #CLKCTL_CCGR1]
        mov r1, #0x4
        str r1, [r0, #CLKCTL_CCSR]
  
+ #if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
+ #elif CONFIG_SYS_CPU_CLK == 600
+       setup_pll PLL1_BASE_ADDR, 600
+ #else
+ #error Unsupported CONFIG_SYS_CPU_CLK value
+ #endif
  
 -        setup_pll PLL3_BASE_ADDR, 400
 +      setup_pll PLL3_BASE_ADDR, 400
+ #ifndef CONFIG_TX53
 -        /* Switch peripheral to PLL3 */
 -        ldr r1, =0x00015154
 -        str r1, [r0, #CLKCTL_CBCMR]
 -        ldr r1, =0x02898945
 -        str r1, [r0, #CLKCTL_CBCDR]
 -        /* make sure change is effective */
 +      /* Switch peripheral to PLL3 */
 +      ldr r0, =CCM_BASE_ADDR
 +      ldr r1, =0x00015154
 +      str r1, [r0, #CLKCTL_CBCMR]
 +      ldr r1, =0x02898945
 +      str r1, [r0, #CLKCTL_CBCDR]
 +      /* make sure change is effective */
  1:      ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
 -        bne 1b
 +      bne 1b
  
 -        setup_pll PLL2_BASE_ADDR, 400
 +      setup_pll PLL2_BASE_ADDR, 400
  
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x00888945
        str r1, [r0, #CLKCTL_CBCDR]
  
        ldr r1, =0x00016154
        str r1, [r0, #CLKCTL_CBCMR]
  
-       /*change uart clk parent to pll2*/
+       /* change uart clk parent to pll2 */
        ldr r1, [r0, #CLKCTL_CSCMR1]
-       and r1, r1, #0xfcffffff
-       orr r1, r1, #0x01000000
+       bic r1, #(0x3 << 24)
+       orr r1, r1, #(0x1 << 24)
        str r1, [r0, #CLKCTL_CSCMR1]
  
        /* make sure change is effective */
  1:      ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
  
 +      setup_pll PLL3_BASE_ADDR, 216
 +
        setup_pll PLL4_BASE_ADDR, 455
  
+ #else /* CONFIG_TX53 */
+       /* Switch peripheral to PLL 3 */
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(0x3 << 12)
+       orr r1, r1, #(1 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       orr r1, r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+ 1:
+       /* make sure change is effective */
+       ldr r1, [r0, #CLKCTL_CDHIPR]
+       tst r1, #0x7f
+       bne 1b
+ #if CONFIG_SYS_SDRAM_CLK == 533
+       setup_pll PLL2_BASE_ADDR, 533
+ #elif CONFIG_SYS_SDRAM_CLK == 400
+       setup_pll PLL2_BASE_ADDR, 400
+ #elif CONFIG_SYS_SDRAM_CLK == 333
+       setup_pll PLL2_BASE_ADDR, 333
+ #else
+ #error Unsupported CONFIG_SYS_SDRAM_CLK
+ #endif
+       /* Switch peripheral to PLL2 */
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       bic r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(3 << 12)
+       orr r1, #(2 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+ #endif
+         setup_pll PLL3_BASE_ADDR, 216
        /* Set the platform clock dividers */
        ldr r0, =ARM_BASE_ADDR
        ldr r1, =0x00000124
  
        /* make uart div=6 */
        ldr r1, [r0, #CLKCTL_CSCDR1]
-       and r1, r1, #0xffffffc0
+       bic r1, #(0x3f << 0)
        orr r1, r1, #0x0a
        str r1, [r0, #CLKCTL_CSCDR1]
+       /* make sure divider effective */
+ 1:    ldr r1, [r0, #CLKCTL_CDHIPR]
+       tst r1, #0x7f
+       bne 1b
  
        /* Restore the default values in the Gate registers */
        ldr r1, =0xFFFFFFFF
        str r1, [r0, #CLKCTL_CCGR6]
        str r1, [r0, #CLKCTL_CCGR7]
  
 -        mov r1, #0x00000
 -        str r1, [r0, #CLKCTL_CCDR]
 +      mov r1, #0x00000
 +      str r1, [r0, #CLKCTL_CCDR]
  
 -        /* for cko - for ARM div by 8 */
 -        mov r1, #0x000A0000
 -        add r1, r1, #0x00000F0
 -        str r1, [r0, #CLKCTL_CCOSR]
 +      /* for cko - for ARM div by 8 */
 +      mov r1, #0x000A0000
 +      add r1, r1, #0x00000F0
 +      str r1, [r0, #CLKCTL_CCOSR]
  
  #endif        /* CONFIG_MX53 */
  .endm
  
 -.macro setup_wdog
 -      ldr r0, =WDOG1_BASE_ADDR
 -      mov r1, #0x30
 -      strh r1, [r0]
 -.endm
 -
  ENTRY(lowlevel_init)
        mov r10, lr
        mov r4, #0      /* Fix R4 to 0 */
@@@ -417,6 -462,9 +465,9 @@@ W_DP_800:          .word DP_OP_80
  W_DP_665:             .word DP_OP_665
                        .word DP_MFD_665
                        .word DP_MFN_665
+ W_DP_600:             .word DP_OP_600
+                       .word DP_MFD_600
+                       .word DP_MFN_600
  #endif
  W_DP_216:             .word DP_OP_216
                        .word DP_MFD_216
@@@ -427,3 -475,6 +478,6 @@@ W_DP_400:               .word DP_OP_40
  W_DP_455:               .word DP_OP_455
                        .word DP_MFD_455
                        .word DP_MFN_455
+ W_DP_533:             .word DP_OP_533
+                       .word DP_MFD_533
+                       .word DP_MFN_533
index 3753c14df3977c7b70459d5db2e3df0a05791f95,978f8499ec4bec1d746582dd8c9ba92ecc5c9487..95564a8257d33fb1e3b8b6a0fa13a3cb87d33b99
  #error "CPU_TYPE not defined"
  #endif
  
+ #ifdef CONFIG_HW_WATCHDOG
+ #define wdog_base     ((void *)WDOG1_BASE_ADDR)
+ #define WDOG_WCR      0x00
+ #define WCR_WDE               (1 << 2)
+ #define WDOG_WSR      0x02
+ void hw_watchdog_reset(void)
+ {
+       if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
+               static u16 toggle = 0xaaaa;
+               writew(toggle, wdog_base + WDOG_WSR);
+               toggle ^= 0xffff;
+       }
+ }
+ #endif
  u32 get_cpu_rev(void)
  {
  #ifdef CONFIG_MX51
@@@ -72,7 -89,7 +89,7 @@@ void enable_caches(void
  #endif
  
  #if defined(CONFIG_FEC_MXC)
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
static void __imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
  {
        int i;
        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
        for (i = 0; i < 6; i++)
                mac[i] = readl(&fuse->mac_addr[i]) & 0xff;
  }
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+       __attribute__((weak, alias("__imx_get_mac_from_fuse")));
  #endif
  
 -void set_chipselect_size(int const cs_size)
 -{
 -      unsigned int reg;
 -      struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 -      reg = readl(&iomuxc_regs->gpr1);
 -
 -      switch (cs_size) {
 -      case CS0_128:
 -              reg &= ~0x7;    /* CS0=128MB, CS1=0, CS2=0, CS3=0 */
 -              reg |= 0x5;
 -              break;
 -      case CS0_64M_CS1_64M:
 -              reg &= ~0x3F;   /* CS0=64MB, CS1=64MB, CS2=0, CS3=0 */
 -              reg |= 0x1B;
 -              break;
 -      case CS0_64M_CS1_32M_CS2_32M:
 -              reg &= ~0x1FF;  /* CS0=64MB, CS1=32MB, CS2=32MB, CS3=0 */
 -              reg |= 0x4B;
 -              break;
 -      case CS0_32M_CS1_32M_CS2_32M_CS3_32M:
 -              reg &= ~0xFFF;  /* CS0=32MB, CS1=32MB, CS2=32MB, CS3=32MB */
 -              reg |= 0x249;
 -              break;
 -      default:
 -              printf("Unknown chip select size: %d\n", cs_size);
 -              break;
 -      }
 -
 -      writel(reg, &iomuxc_regs->gpr1);
 -}
 -
 -void cpu_cache_initialization(void)
 -{
 -      printf("Enabling L2 cache\n");
 -      asm volatile(
 -              "mrc 15, 0, r0, c1, c0, 1\n"
 -              "orr r0, r0, #0x2\n"
 -              "mcr 15, 0, r0, c1, c0, 1\n"
 -              : : : "r0", "memory"
 -              );
 -}
 -
  #ifdef CONFIG_MX53
  void boot_mode_apply(unsigned cfg_val)
  {
index 055f44e8e46c210f3bd94dba47c130185192d3be,8a494b48e87c55ed57869d2ef839bf05c58c6f98..dfd5e08a0276e3dbf7f225926dd37cc889889d02
@@@ -5,7 -5,6 +5,7 @@@
   */
  
  #include <common.h>
 +#include <div64.h>
  #include <asm/io.h>
  #include <asm/errno.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/sys_proto.h>
  
  enum pll_clocks {
-       PLL_SYS,        /* System PLL */
-       PLL_BUS,        /* System Bus PLL*/
-       PLL_USBOTG,     /* OTG USB PLL */
-       PLL_ENET,       /* ENET PLL */
+       PLL_ARM,        /* PLL1: ARM PLL */
 -      PLL_BUS,        /* PLL2: System Bus PLL*/
++      PLL_528,        /* PLL2: System Bus PLL*/
+       PLL_USBOTG,     /* PLL3: OTG USB PLL */
+       PLL_AUDIO,      /* PLL4: Audio PLL */
+       PLL_VIDEO,      /* PLL5: Video PLL */
+       PLL_ENET,       /* PLL6: ENET PLL */
+       PLL_USB2,       /* PLL7: USB2 PLL */
+       PLL_MLB,        /* PLL8: MLB PLL */
  };
  
- struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
+ struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+ int clk_enable(struct clk *clk)
+ {
+       int ret = 0;
+       if (!clk)
+               return 0;
+       if (clk->usecount == 0) {
 -debug("%s: Enabling %s clock\n", __func__, clk->name);
++              debug("%s: Enabling %s clock\n", __func__, clk->name);
+               ret = clk->enable(clk);
+               if (ret)
+                       return ret;
+               clk->usecount++;
+       }
+       assert(clk->usecount > 0);
+       return ret;
+ }
+ void clk_disable(struct clk *clk)
+ {
+       if (!clk)
+               return;
+       assert(clk->usecount > 0);
+       if (!(--clk->usecount)) {
+               if (clk->disable) {
 -debug("%s: Disabling %s clock\n", __func__, clk->name);
++                      debug("%s: Disabling %s clock\n", __func__, clk->name);
+                       clk->disable(clk);
+               }
+       }
+ }
+ int clk_get_usecount(struct clk *clk)
+ {
+       if (clk == NULL)
+               return 0;
+       return clk->usecount;
+ }
+ u32 clk_get_rate(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk->rate;
+ }
+ struct clk *clk_get_parent(struct clk *clk)
+ {
+       if (!clk)
+               return 0;
+       return clk->parent;
+ }
+ int clk_set_rate(struct clk *clk, unsigned long rate)
+ {
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+ }
+ long clk_round_rate(struct clk *clk, unsigned long rate)
+ {
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+       return clk->round_rate(clk, rate);
+ }
+ int clk_set_parent(struct clk *clk, struct clk *parent)
+ {
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+       if (!clk || clk == parent)
+               return 0;
+       if (clk->set_parent) {
+               int ret;
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+ }
  
  #ifdef CONFIG_MXC_OCOTP
  void enable_ocotp_clk(unsigned char enable)
  }
  #endif
  
 +#ifdef CONFIG_NAND_MXS
 +void setup_gpmi_io_clk(u32 cfg)
 +{
 +      /* Disable clocks per ERR007177 from MX6 errata */
 +      clrbits_le32(&imx_ccm->CCGR4,
 +                   MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
 +
 +      clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
 +
 +      clrsetbits_le32(&imx_ccm->cs2cdr,
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
 +                      cfg);
 +
 +      setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
 +      setbits_le32(&imx_ccm->CCGR4,
 +                   MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
 +}
 +#endif
 +
  void enable_usboh3_clk(unsigned char enable)
  {
        u32 reg;
  
  }
  
 -#ifdef CONFIG_I2C_MXC
 +#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX)
 +void enable_enet_clk(unsigned char enable)
 +{
 +      u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK;
 +
 +      if (enable)
 +              setbits_le32(&imx_ccm->CCGR1, mask);
 +      else
 +              clrbits_le32(&imx_ccm->CCGR1, mask);
 +}
 +#endif
 +
 +#ifdef CONFIG_MXC_UART
 +void enable_uart_clk(unsigned char enable)
 +{
 +      u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK;
 +
 +      if (enable)
 +              setbits_le32(&imx_ccm->CCGR5, mask);
 +      else
 +              clrbits_le32(&imx_ccm->CCGR5, mask);
 +}
 +#endif
 +
 +#ifdef CONFIG_SPI
 +/* spi_num can be from 0 - 4 */
 +int enable_cspi_clock(unsigned char enable, unsigned spi_num)
 +{
 +      u32 mask;
 +
 +      if (spi_num > 4)
 +              return -EINVAL;
 +
 +      mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2);
 +      if (enable)
 +              setbits_le32(&imx_ccm->CCGR1, mask);
 +      else
 +              clrbits_le32(&imx_ccm->CCGR1, mask);
 +
 +      return 0;
 +}
 +#endif
 +
 +#ifdef CONFIG_MMC
 +int enable_usdhc_clk(unsigned char enable, unsigned bus_num)
 +{
 +      u32 mask;
 +
 +      if (bus_num > 3)
 +              return -EINVAL;
 +
 +      mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2);
 +      if (enable)
 +              setbits_le32(&imx_ccm->CCGR6, mask);
 +      else
 +              clrbits_le32(&imx_ccm->CCGR6, mask);
 +
 +      return 0;
 +}
 +#endif
 +
 +#ifdef CONFIG_SYS_I2C_MXC
  /* i2c_num can be from 0 - 2 */
  int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  {
  }
  #endif
  
 +/* spi_num can be from 0 - SPI_MAX_NUM */
 +int enable_spi_clk(unsigned char enable, unsigned spi_num)
 +{
 +      u32 reg;
 +      u32 mask;
 +
 +      if (spi_num > SPI_MAX_NUM)
 +              return -EINVAL;
 +
 +      mask = MXC_CCM_CCGR_CG_MASK << (spi_num << 1);
 +      reg = __raw_readl(&imx_ccm->CCGR1);
 +      if (enable)
 +              reg |= mask;
 +      else
 +              reg &= ~mask;
 +      __raw_writel(reg, &imx_ccm->CCGR1);
 +      return 0;
 +}
  static u32 decode_pll(enum pll_clocks pll, u32 infreq)
  {
        u32 div;
  
        switch (pll) {
-       case PLL_SYS:
-               div = __raw_readl(&imx_ccm->analog_pll_sys);
-               div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
-               return (infreq * div) >> 1;
-       case PLL_BUS:
-               div = __raw_readl(&imx_ccm->analog_pll_528);
+       case PLL_ARM:
+               div = __raw_readl(&anatop->pll_arm);
+               if (div & BM_ANADIG_PLL_ARM_BYPASS)
+                       /* Assume the bypass clock is always derived from OSC */
+                       return infreq;
+               div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
+               return infreq * div / 2;
 -      case PLL_BUS:
++      case PLL_528:
+               div = __raw_readl(&anatop->pll_528);
 -              if (div & BM_ANADIG_PLL_SYS_BYPASS)
++              if (div & BM_ANADIG_PLL_528_BYPASS)
+                       return infreq;
 -              div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
 +              div &= BM_ANADIG_PLL_528_DIV_SELECT;
  
-               return infreq * (20 + (div << 1));
+               return infreq * (20 + div * 2);
        case PLL_USBOTG:
-               div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
-               div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
-               return infreq * (20 + (div << 1));
+               div = __raw_readl(&anatop->usb1_pll_480_ctrl);
 -              if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
++              if (div & BM_ANADIG_USB_PLL_480_CTRL_BYPASS)
+                       return infreq;
 -              div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
++              div &= BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT;
+               return infreq * (20 + div * 2);
+       case PLL_AUDIO:
+               div = __raw_readl(&anatop->pll_audio);
+               if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
+               return infreq * div;
+       case PLL_VIDEO:
+               div = __raw_readl(&anatop->pll_video);
+               if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
+               return infreq * div;
        case PLL_ENET:
-               div = __raw_readl(&imx_ccm->analog_pll_enet);
+               div = __raw_readl(&anatop->pll_enet);
+               if (div & BM_ANADIG_PLL_ENET_BYPASS)
+                       return infreq;
                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
  
 -              return (div == 3 ? 125000000 : 25000000 * div * 2);
 +              return 25000000 * (div + (div >> 1) + 1);
-       default:
+       case PLL_USB2:
+               div = __raw_readl(&anatop->usb2_pll_480_ctrl);
 -              if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
++              if (div & BM_ANADIG_USB_PLL_480_CTRL_BYPASS)
+                       return infreq;
 -              div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
++              div &= BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT;
+               return infreq * (20 + div * 2);
+       case PLL_MLB:
+               div = __raw_readl(&anatop->pll_mlb);
+               if (div & BM_ANADIG_PLL_MLB_BYPASS)
+                       return infreq;
+               /* unknown external clock provided on MLB_CLK pin */
                return 0;
        }
-       /* NOTREACHED */
+       return 0;
  }
-       case PLL_BUS:
 +static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
 +{
 +      u32 div;
 +      u64 freq;
++      struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 +
 +      switch (pll) {
-                       /* No PFD3 on PPL2 */
++      case PLL_528:
 +              if (pfd_num == 3) {
-               div = __raw_readl(&imx_ccm->analog_pfd_528);
-               freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
++                      /* No PFD3 on PLL2 */
 +                      return 0;
 +              }
-               div = __raw_readl(&imx_ccm->analog_pfd_480);
++              div = __raw_readl(&anatop->pfd_528);
++              freq = (u64)decode_pll(PLL_528, MXC_HCLK);
 +              break;
 +      case PLL_USBOTG:
-               /* No PFD on other PLL                                       */
++              div = __raw_readl(&anatop->pfd_480);
 +              freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK);
 +              break;
 +      default:
++              /* No PFD on other PLL */
 +              return 0;
 +      }
 +
 +      return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >>
 +                            ANATOP_PFD_FRAC_SHIFT(pfd_num));
 +}
  
  static u32 get_mcu_main_clk(void)
  {
        reg = __raw_readl(&imx_ccm->cacrr);
        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
+       freq = decode_pll(PLL_ARM, MXC_HCLK);
  
        return freq / (reg + 1);
  }
@@@ -266,8 -259,6 +395,6 @@@ u32 get_periph_clk(void
                case 2:
                        freq = MXC_HCLK;
                        break;
-               default:
-                       break;
                }
        } else {
                reg = __raw_readl(&imx_ccm->cbcmr);
  
                switch (reg) {
                case 0:
--                      freq = decode_pll(PLL_BUS, MXC_HCLK);
++                      freq = decode_pll(PLL_528, MXC_HCLK);
                        break;
                case 1:
-                       freq = mxc_get_pll_pfd(PLL_BUS, 2);
 -                      freq = PLL2_PFD2_FREQ;
++                      freq = mxc_get_pll_pfd(PLL_528, 2);
                        break;
                case 2:
-                       freq = mxc_get_pll_pfd(PLL_BUS, 0);
 -                      freq = PLL2_PFD0_FREQ;
++                      freq = mxc_get_pll_pfd(PLL_528, 0);
                        break;
                case 3:
 -                      freq = PLL2_PFD2_DIV_FREQ;
 +                      /* static / 2 divider */
-                       freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
-                       break;
-               default:
++                      freq = mxc_get_pll_pfd(PLL_528, 2) / 2;
                        break;
                }
        }
@@@ -312,10 -300,6 +437,10 @@@ static u32 get_ipg_per_clk(void
        u32 reg, perclk_podf;
  
        reg = __raw_readl(&imx_ccm->cscmr1);
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
 +      if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK)
 +              return MXC_HCLK; /* OSC 24Mhz */
 +#endif
        perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
  
        return get_ipg_clk() / (perclk_podf + 1);
  static u32 get_uart_clk(void)
  {
        u32 reg, uart_podf;
 -      u32 freq = PLL3_80M;
 +      u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */
        reg = __raw_readl(&imx_ccm->cscdr1);
 -#ifdef CONFIG_MX6SL
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
        if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
                freq = MXC_HCLK;
  #endif
@@@ -344,7 -328,7 +469,7 @@@ static u32 get_cspi_clk(void
        reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
        cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
  
 -      return  PLL3_60M / (cspi_podf + 1);
 +      return  decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1));
  }
  
  static u32 get_axi_clk(void)
  
        if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
                if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
-                       root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
 -                      root_freq = PLL2_PFD2_FREQ;
++                      root_freq = mxc_get_pll_pfd(PLL_528, 2);
                else
 -                      root_freq = PLL3_PFD1_FREQ;
 +                      root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
        } else
                root_freq = get_periph_clk();
  
  
  static u32 get_emi_slow_clk(void)
  {
 -      u32 emi_clk_sel, emi_slow_pof, cscmr1, root_freq = 0;
 +      u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0;
  
        cscmr1 =  __raw_readl(&imx_ccm->cscmr1);
        emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
        emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
 -      emi_slow_pof = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
 -      emi_slow_pof >>= MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
 +      emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
 +      emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
  
        switch (emi_clk_sel) {
        case 0:
                root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
                break;
        case 2:
-               root_freq =  mxc_get_pll_pfd(PLL_BUS, 2);
 -              root_freq = PLL2_PFD2_FREQ;
++              root_freq =  mxc_get_pll_pfd(PLL_528, 2);
                break;
        case 3:
-               root_freq =  mxc_get_pll_pfd(PLL_BUS, 0);
 -              root_freq = PLL2_PFD0_FREQ;
++              root_freq =  mxc_get_pll_pfd(PLL_528, 0);
                break;
        }
  
 -      return root_freq / (emi_slow_pof + 1);
 +      return root_freq / (emi_slow_podf + 1);
  }
  
 -              root_freq = PLL2_PFD0_FREQ;
+ static u32 get_nfc_clk(void)
+ {
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+       u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+       int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
+               MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+       u32 root_freq;
+       switch (nfc_clk_sel) {
+       case 0:
 -              root_freq = decode_pll(PLL_BUS, MXC_HCLK);
++              root_freq = mxc_get_pll_pfd(PLL_528, 0);
+               break;
+       case 1:
 -              root_freq = PLL2_PFD2_FREQ;
++              root_freq = decode_pll(PLL_528, MXC_HCLK);
+               break;
+       case 2:
+               root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+               break;
+       case 3:
 -                      root_freq = PLL2_PFD0_FREQ;
++              root_freq = mxc_get_pll_pfd(PLL_528, 2);
+               break;
+       }
+       return root_freq / (pred + 1) / (podf + 1);
+ }
+ #define CS2CDR_ENFC_MASK      (MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |    \
+                               MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |     \
+                               MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK)
+ static int set_nfc_clk(u32 ref, u32 freq_khz)
+ {
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf;
+       u32 pred;
+       int nfc_clk_sel;
+       u32 root_freq;
+       u32 min_err = ~0;
+       u32 nfc_val = ~0;
+       u32 freq = freq_khz * 1000;
+       for (nfc_clk_sel = 0; nfc_clk_sel < 4; nfc_clk_sel++) {
+               u32 act_freq;
+               u32 err;
+               if (ref < 4 && ref != nfc_clk_sel)
+                       continue;
+               switch (nfc_clk_sel) {
+               case 0:
 -                      root_freq = decode_pll(PLL_BUS, MXC_HCLK);
++                      root_freq = mxc_get_pll_pfd(PLL_528, 0);
+                       break;
+               case 1:
 -                      root_freq = PLL2_PFD2_FREQ;
++                      root_freq = decode_pll(PLL_528, MXC_HCLK);
+                       break;
+               case 2:
+                       root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+                       break;
+               case 3:
 -              podf = min(DIV_ROUND_UP(root_freq, freq), 1 << 6);
 -              pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8);
++                      root_freq = mxc_get_pll_pfd(PLL_528, 2);
+                       break;
+               }
+               if (root_freq < freq)
+                       continue;
 -#ifdef CONFIG_MX6SL
++              podf = min(DIV_ROUND_UP(root_freq, freq), 1U << 6);
++              pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8U);
+               act_freq = root_freq / pred / podf;
+               err = (freq - act_freq) * 100 / freq;
+               debug("root=%d[%u] freq=%u pred=%u podf=%u act=%u err=%d\n",
+                       nfc_clk_sel, root_freq, freq, pred, podf, act_freq, err);
+               if (act_freq > freq)
+                       continue;
+               if (err < min_err) {
+                       nfc_val = (podf - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+                       nfc_val |= (pred - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+                       nfc_val |= nfc_clk_sel << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+       if (nfc_val == ~0 || min_err > 10)
+               return -EINVAL;
+       if ((cs2cdr & CS2CDR_ENFC_MASK) != nfc_val) {
+               debug("changing cs2cdr from %08x to %08x\n", cs2cdr,
+                       (cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val);
+               __raw_writel((cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val,
+                       &imx_ccm->cs2cdr);
+       } else {
+               debug("Leaving cs2cdr unchanged [%08x]\n", cs2cdr);
+       }
+       return 0;
+ }
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
  static u32 get_mmdc_ch0_clk(void)
  {
        u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
        switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
                MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
        case 0:
--              freq = decode_pll(PLL_BUS, MXC_HCLK);
++              freq = decode_pll(PLL_528, MXC_HCLK);
                break;
        case 1:
-               freq = mxc_get_pll_pfd(PLL_BUS, 2);
 -              freq = PLL2_PFD2_FREQ;
++              freq = mxc_get_pll_pfd(PLL_528, 2);
                break;
        case 2:
-               freq = mxc_get_pll_pfd(PLL_BUS, 0);
 -              freq = PLL2_PFD0_FREQ;
++              freq = mxc_get_pll_pfd(PLL_528, 0);
                break;
        case 3:
 -              freq = PLL2_PFD2_DIV_FREQ;
 +              /* static / 2 divider */
-               freq =  mxc_get_pll_pfd(PLL_BUS, 2) / 2;
++              freq =  mxc_get_pll_pfd(PLL_528, 2) / 2;
        }
  
        return freq / (podf + 1);
@@@ -434,114 -515,6 +657,114 @@@ static u32 get_mmdc_ch0_clk(void
  }
  #endif
  
 +#ifdef CONFIG_MX6SX
 +/* qspi_num can be from 0 - 1 */
 +void enable_qspi_clk(int qspi_num)
 +{
 +      u32 reg = 0;
 +      /* Enable QuadSPI clock */
 +      switch (qspi_num) {
 +      case 0:
 +              /* disable the clock gate */
 +              clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
 +
 +              /* set 50M  : (50 = 396 / 2 / 4) */
 +              reg = readl(&imx_ccm->cscmr1);
 +              reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK |
 +                       MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK);
 +              reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) |
 +                      (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET));
 +              writel(reg, &imx_ccm->cscmr1);
 +
 +              /* enable the clock gate */
 +              setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
 +              break;
 +      case 1:
 +              /*
 +               * disable the clock gate
 +               * QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate,
 +               * disable both of them.
 +               */
 +              clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
 +                           MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
 +
 +              /* set 50M  : (50 = 396 / 2 / 4) */
 +              reg = readl(&imx_ccm->cs2cdr);
 +              reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK |
 +                       MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK |
 +                       MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK);
 +              reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) |
 +                      MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3));
 +              writel(reg, &imx_ccm->cs2cdr);
 +
 +              /*enable the clock gate*/
 +              setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
 +                           MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
 +              break;
 +      default:
 +              break;
 +      }
 +}
 +#endif
 +
 +#ifdef CONFIG_FEC_MXC
 +int enable_fec_anatop_clock(enum enet_freq freq)
 +{
 +      u32 reg = 0;
 +      s32 timeout = 100000;
 +
 +      struct anatop_regs __iomem *anatop =
 +              (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 +
 +      if (freq < ENET_25MHZ || freq > ENET_125MHZ)
 +              return -EINVAL;
 +
 +      reg = readl(&anatop->pll_enet);
 +      reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
 +      reg |= freq;
 +
 +      if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||
 +          (!(reg & BM_ANADIG_PLL_ENET_LOCK))) {
 +              reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
 +              writel(reg, &anatop->pll_enet);
 +              while (timeout--) {
 +                      if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
 +                              break;
 +              }
 +              if (timeout < 0)
 +                      return -ETIMEDOUT;
 +      }
 +
 +      /* Enable FEC clock */
 +      reg |= BM_ANADIG_PLL_ENET_ENABLE;
 +      reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
 +      writel(reg, &anatop->pll_enet);
 +
 +#ifdef CONFIG_MX6SX
 +      /*
 +       * Set enet ahb clock to 200MHz
 +       * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
 +       */
 +      reg = readl(&imx_ccm->chsccdr);
 +      reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK
 +               | MXC_CCM_CHSCCDR_ENET_PODF_MASK
 +               | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK);
 +      /* PLL2 PFD2 */
 +      reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET);
 +      /* Div = 2*/
 +      reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET);
 +      reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET);
 +      writel(reg, &imx_ccm->chsccdr);
 +
 +      /* Enable enet system clock */
 +      reg = readl(&imx_ccm->CCGR3);
 +      reg |= MXC_CCM_CCGR3_ENET_MASK;
 +      writel(reg, &imx_ccm->CCGR3);
 +#endif
 +      return 0;
 +}
 +#endif
 +
  static u32 get_usdhc_clk(u32 port)
  {
        u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
        }
  
        if (clk_sel)
-               root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
 -              root_freq = PLL2_PFD0_FREQ;
++              root_freq = mxc_get_pll_pfd(PLL_528, 0);
        else
-               root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
 -              root_freq = PLL2_PFD2_FREQ;
++              root_freq = mxc_get_pll_pfd(PLL_528, 2);
  
        return root_freq / (usdhc_podf + 1);
  }
@@@ -592,175 -565,130 +815,265 @@@ u32 imx_get_uartclk(void
  
  u32 imx_get_fecclk(void)
  {
 -      return decode_pll(PLL_ENET, MXC_HCLK);
 +      return mxc_get_clock(MXC_IPG_CLK);
  }
  
 -int enable_sata_clock(void)
 +static int enable_enet_pll(uint32_t en)
  {
-       struct mxc_ccm_reg *const imx_ccm
-               = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
+       u32 reg;
        s32 timeout = 100000;
-       u32 reg = 0;
  
 -      /* Enable sata clock */
 -      reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
 -      reg |= MXC_CCM_CCGR5_SATA_MASK;
 -      writel(reg, &imx_ccm->CCGR5);
 -
        /* Enable PLLs */
-       reg = readl(&imx_ccm->analog_pll_enet);
-       reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
-       writel(reg, &imx_ccm->analog_pll_enet);
-       reg |= BM_ANADIG_PLL_SYS_ENABLE;
+       reg = readl(&anatop->pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
+       writel(reg, &anatop->pll_enet);
+       reg |= BM_ANADIG_PLL_ENET_ENABLE;
        while (timeout--) {
-               if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
+               if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
                        break;
        }
        if (timeout <= 0)
                return -EIO;
-       reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
+       writel(reg, &anatop->pll_enet);
 -      reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
 +      reg |= en;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       writel(reg, &anatop->pll_enet);
 +      return 0;
 +}
 +
 +#ifndef CONFIG_MX6SX
 +static void ungate_sata_clock(void)
 +{
 +      struct mxc_ccm_reg *const imx_ccm =
 +              (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  
 -      return 0 ;
 +      /* Enable SATA clock. */
 +      setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
 +}
 +#endif
 +
 +static void ungate_pcie_clock(void)
 +{
 +      struct mxc_ccm_reg *const imx_ccm =
 +              (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +
 +      /* Enable PCIe clock. */
 +      setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
 +}
 +
 +#ifndef CONFIG_MX6SX
 +int enable_sata_clock(void)
 +{
 +      ungate_sata_clock();
 +      return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
 +}
 +
 +void disable_sata_clock(void)
 +{
 +      struct mxc_ccm_reg *const imx_ccm =
 +              (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +
 +      clrbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
 +}
 +#endif
 +
 +int enable_pcie_clock(void)
 +{
 +      struct anatop_regs *anatop_regs =
 +              (struct anatop_regs *)ANATOP_BASE_ADDR;
 +      struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      u32 lvds1_clk_sel;
 +
 +      /*
 +       * Here be dragons!
 +       *
 +       * The register ANATOP_MISC1 is not documented in the Freescale
 +       * MX6RM. The register that is mapped in the ANATOP space and
 +       * marked as ANATOP_MISC1 is actually documented in the PMU section
 +       * of the datasheet as PMU_MISC1.
 +       *
 +       * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on
 +       * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important
 +       * for PCI express link that is clocked from the i.MX6.
 +       */
 +#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN                (1 << 12)
 +#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN                (1 << 10)
 +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK   0x0000001F
 +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF       0xa
 +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF       0xb
 +
 +      if (is_cpu_type(MXC_CPU_MX6SX))
 +              lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF;
 +      else
 +              lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF;
 +
 +      clrsetbits_le32(&anatop_regs->ana_misc1,
 +                      ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
 +                      ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
 +                      ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel);
 +
 +      /* PCIe reference clock sourced from AXI. */
 +      clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
 +
 +      /* Party time! Ungate the clock to the PCIe. */
 +#ifndef CONFIG_MX6SX
 +      ungate_sata_clock();
 +#endif
 +      ungate_pcie_clock();
 +
 +      return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
 +                             BM_ANADIG_PLL_ENET_ENABLE_PCIE);
 +}
 +
 +#ifdef CONFIG_SECURE_BOOT
 +void hab_caam_clock_enable(unsigned char enable)
 +{
 +      u32 reg;
 +
 +      /* CG4 ~ CG6, CAAM clocks */
 +      reg = __raw_readl(&imx_ccm->CCGR0);
 +      if (enable)
 +              reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
 +                      MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
 +                      MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
 +      else
 +              reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
 +                      MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
 +                      MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
 +      __raw_writel(reg, &imx_ccm->CCGR0);
 +
 +      /* EMI slow clk */
 +      reg = __raw_readl(&imx_ccm->CCGR6);
 +      if (enable)
 +              reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
 +      else
 +              reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
 +      __raw_writel(reg, &imx_ccm->CCGR6);
 +}
 +#endif
 +
 +static void enable_pll3(void)
 +{
 +      struct anatop_regs __iomem *anatop =
 +              (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 +
 +      /* make sure pll3 is enabled */
 +      if ((readl(&anatop->usb1_pll_480_ctrl) &
-                       BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
++                      BM_ANADIG_USB_PLL_480_CTRL_LOCK) == 0) {
 +              /* enable pll's power */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
++              writel(BM_ANADIG_USB_PLL_480_CTRL_POWER,
 +                     &anatop->usb1_pll_480_ctrl_set);
 +              writel(0x80, &anatop->ana_misc2_clr);
 +              /* wait for pll lock */
 +              while ((readl(&anatop->usb1_pll_480_ctrl) &
-                       BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
++                      BM_ANADIG_USB_PLL_480_CTRL_LOCK) == 0)
 +                      ;
 +              /* disable bypass */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
++              writel(BM_ANADIG_USB_PLL_480_CTRL_BYPASS,
 +                     &anatop->usb1_pll_480_ctrl_clr);
 +              /* enable pll output */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
++              writel(BM_ANADIG_USB_PLL_480_CTRL_ENABLE,
 +                     &anatop->usb1_pll_480_ctrl_set);
 +      }
 +}
 +
 +void enable_thermal_clk(void)
 +{
 +      enable_pll3();
  }
  
+ void ipu_clk_enable(void)
+ {
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+ }
+ void ipu_clk_disable(void)
+ {
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg &= ~MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+ }
+ void ipu_di_clk_enable(int di)
+ {
+       switch (di) {
+       case 0:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
+               break;
+       case 1:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+ }
+ void ipu_di_clk_disable(int di)
+ {
+       switch (di) {
+       case 0:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
+               break;
+       case 1:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+ }
+ void ldb_clk_enable(int ldb)
+ {
+       switch (ldb) {
+       case 0:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI0_MASK);
+               break;
+       case 1:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+ }
+ void ldb_clk_disable(int ldb)
+ {
+       switch (ldb) {
+       case 0:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI0_MASK);
+               break;
+       case 1:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+ }
+ void ocotp_clk_enable(void)
+ {
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+ }
+ void ocotp_clk_disable(void)
+ {
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+ }
  unsigned int mxc_get_clock(enum mxc_clock clk)
  {
        switch (clk) {
                return get_usdhc_clk(3);
        case MXC_SATA_CLK:
                return get_ahb_clk();
-               break;
+       case MXC_NFC_CLK:
+               return get_nfc_clk();
 +      default:
 +              printf("Unsupported MXC CLK: %d\n", clk);
        }
  
 -      return -1;
 +      return 0;
  }
  
+ static inline int gcd(int m, int n)
+ {
+       int t;
+       while (m > 0) {
+               if (n > m) {
+                       t = m;
+                       m = n;
+                       n = t;
+               } /* swap */
+               m -= n;
+       }
+       return n;
+ }
+ /* Config CPU clock */
+ static int set_arm_clk(u32 ref, u32 freq_khz)
+ {
+       int d;
+       int div = 0;
+       int mul = 0;
+       u32 min_err = ~0;
+       u32 reg;
+       if (freq_khz > ref / 1000 * 108 / 2 || freq_khz < ref / 1000 * 54 / 8 / 2) {
+               printf("Frequency %u.%03uMHz is out of range: %u.%03u..%u.%03u\n",
+                       freq_khz / 1000, freq_khz % 1000,
+                       54 * ref / 1000000 / 8 / 2, 54 * ref / 1000 / 8 / 2 % 1000,
+                       108 * ref / 1000000 / 2, 108 * ref / 1000 / 2 % 1000);
+               return -EINVAL;
+       }
+       for (d = DIV_ROUND_UP(648000, freq_khz); d <= 8; d++) {
+               int m = freq_khz * 2 * d / (ref / 1000);
+               u32 f;
+               u32 err;
+               if (m > 108) {
+                       debug("%s@%d: d=%d m=%d\n", __func__, __LINE__,
+                               d, m);
+                       break;
+               }
+               f = ref * m / d / 2;
+               if (f > freq_khz * 1000) {
+                       debug("%s@%d: d=%d m=%d f=%u freq=%u\n", __func__, __LINE__,
+                               d, m, f, freq_khz);
+                       if (--m < 54)
+                               return -EINVAL;
+                       f = ref * m / d / 2;
+               }
+               err = freq_khz * 1000 - f;
+               debug("%s@%d: d=%d m=%d f=%u freq=%u err=%d\n", __func__, __LINE__,
+                       d, m, f, freq_khz, err);
+               if (err < min_err) {
+                       mul = m;
+                       div = d;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+       if (min_err == ~0)
+               return -EINVAL;
+       debug("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
+               mul, div, freq_khz / 1000, freq_khz % 1000,
+               ref * mul / 2 / div / 1000000, ref * mul / 2 / div / 1000 % 1000);
+       reg = readl(&anatop->pll_arm);
+       debug("anadig_pll_arm=%08x -> %08x\n",
+               reg, (reg & ~0x7f) | mul);
+       reg |= 1 << 16;
+       writel(reg, &anatop->pll_arm); /* bypass PLL */
+       reg = (reg & ~0x7f) | mul;
+       writel(reg, &anatop->pll_arm);
+       writel(div - 1, &imx_ccm->cacrr);
+       reg &= ~(1 << 16);
+       writel(reg, &anatop->pll_arm); /* disable PLL bypass */
+       return 0;
+ }
  /*
-  * Dump some core clockes.
+  * This function assumes the expected core clock has to be changed by
+  * modifying the PLL. This is NOT true always but for most of the times,
+  * it is. So it assumes the PLL output freq is the same as the expected
+  * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
+  * In the latter case, it will try to increase the presc value until
+  * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
+  * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
+  * on the targeted PLL and reference input clock to the PLL. Lastly,
+  * it sets the register based on these values along with the dividers.
+  * Note 1) There is no value checking for the passed-in divider values
+  *         so the caller has to make sure those values are sensible.
+  *      2) Also adjust the NFC divider such that the NFC clock doesn't
+  *         exceed NFC_CLK_MAX.
+  *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
+  *         177MHz for higher voltage, this function fixes the max to 133MHz.
+  *      4) This function should not have allowed diag_printf() calls since
+  *         the serial driver has been stoped. But leave then here to allow
+  *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
   */
- int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
- {
-       u32 freq;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
-       printf("PLL_SYS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_BUS, MXC_HCLK);
-       printf("PLL_BUS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_USBOTG, MXC_HCLK);
-       printf("PLL_OTG    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_ENET, MXC_HCLK);
-       printf("PLL_NET    %8d MHz\n", freq / 1000000);
+ int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
+ {
+       int ret;
+       freq *= 1000;
+       switch (clk) {
+       case MXC_ARM_CLK:
+               ret = set_arm_clk(ref, freq);
+               break;
+       case MXC_NFC_CLK:
+               ret = set_nfc_clk(ref, freq);
+               break;
+       default:
+               printf("Warning: Unsupported or invalid clock type: %d\n",
+                       clk);
+               return -EINVAL;
+       }
+       return ret;
+ }
+ /*
+  * Dump some core clocks.
+  */
+ #define print_pll(pll)        {                               \
+       u32 __pll = decode_pll(pll, MXC_HCLK);          \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+ #define MXC_IPG_PER_CLK       MXC_IPG_PERCLK
  
 -      print_pll(PLL_BUS);
+ #define print_clk(clk)        {                               \
+       u32 __clk = mxc_get_clock(MXC_##clk##_CLK);     \
+       printf("%-12s %4d.%03d MHz\n", #clk,            \
+               __clk / 1000000, __clk / 1000 % 1000);  \
+       }
+ #define print_pfd(pll, pfd)   {                                       \
+       u32 __pfd = readl(&anatop->pfd_##pll);                          \
+       if (__pfd & (0x80 << 8 * pfd)) {                                \
+               printf("PFD_%s[%d]      OFF\n", #pll, pfd);             \
+       } else {                                                        \
+               __pfd = (__pfd >> 8 * pfd) & 0x3f;                      \
+               printf("PFD_%s[%d]   %4d.%03d MHz\n", #pll, pfd,        \
+                       pll * 18 / __pfd,                               \
+                       pll * 18 * 1000 / __pfd % 1000);                \
+       }                                                               \
+ }
+ static void do_mx6_showclocks(void)
+ {
+       print_pll(PLL_ARM);
++      print_pll(PLL_528);
+       print_pll(PLL_USBOTG);
+       print_pll(PLL_AUDIO);
+       print_pll(PLL_VIDEO);
+       print_pll(PLL_ENET);
+       print_pll(PLL_USB2);
        printf("\n");
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
- #ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
- #endif
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
-       printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
-       printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
-       printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
-       printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
-       printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
  
-       return 0;
+       print_pfd(480, 0);
+       print_pfd(480, 1);
+       print_pfd(480, 2);
+       print_pfd(480, 3);
+       print_pfd(528, 0);
+       print_pfd(528, 1);
+       print_pfd(528, 2);
+       printf("\n");
+       print_clk(IPG);
+       print_clk(UART);
+       print_clk(CSPI);
+       print_clk(AHB);
+       print_clk(AXI);
+       print_clk(DDR);
+       print_clk(ESDHC);
+       print_clk(ESDHC2);
+       print_clk(ESDHC3);
+       print_clk(ESDHC4);
+       print_clk(EMI_SLOW);
+       print_clk(NFC);
+       print_clk(IPG_PER);
+       print_clk(ARM);
+ }
+ static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+ } mx6_clk_lookup[] = {
+       { "arm", MXC_ARM_CLK, },
+       { "nfc", MXC_NFC_CLK, },
+ };
+ int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int i;
+       unsigned long freq;
+       unsigned long ref = ~0UL;
+       if (argc < 2) {
+               do_mx6_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq == 0) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+               if (strcasecmp(argv[1], mx6_clk_lookup[i].name) == 0) {
+                       switch (mx6_clk_lookup[i].index) {
+                       case MXC_ARM_CLK:
+                               if (argc > 3)
+                                       return CMD_RET_USAGE;
 -                              ref = CONFIG_SYS_MX6_HCLK;
++                              ref = MXC_HCLK;
+                               break;
+                       case MXC_NFC_CLK:
+                               if (argc > 3 && ref > 3) {
+                                       printf("Invalid clock selector value: %lu\n", ref);
+                                       return CMD_RET_FAILURE;
+                               }
+                               break;
+                       }
+                       printf("Setting %s clock to %lu MHz\n",
+                               mx6_clk_lookup[i].name, freq);
+                       if (mxc_set_clock(ref, freq, mx6_clk_lookup[i].index))
+                               break;
+                       freq = mxc_get_clock(mx6_clk_lookup[i].index);
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               mx6_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(mx6_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+                       printf("\t%s\n", mx6_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
  }
  
 +#ifndef CONFIG_MX6SX
 +void enable_ipu_clock(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      int reg;
 +      reg = readl(&mxc_ccm->CCGR3);
 +      reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
 +      writel(reg, &mxc_ccm->CCGR3);
 +}
 +#endif
  /***************************************************/
  
  U_BOOT_CMD(
-       clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
-       "display clocks",
-       ""
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
  );
index 5f5f49720107f56717e676eafbfd94983ffee9b4,6ca4a1ee7d5a77dad92148e81a5f5a34c3910f83..5cf472d24f3393ea8aa8e0bdfb17f27230983529
@@@ -8,28 -8,42 +8,54 @@@
   */
  
  #include <common.h>
 -#include <div64.h>
 +#include <asm/armv7.h>
 +#include <asm/bootm.h>
 +#include <asm/pl310.h>
  #include <asm/errno.h>
  #include <asm/io.h>
  #include <asm/arch/imx-regs.h>
+ #include <asm/arch/crm_regs.h>
+ #include <asm/arch/regs-ocotp.h>
  #include <asm/arch/clock.h>
  #include <asm/arch/sys_proto.h>
  #include <asm/imx-common/boot_mode.h>
  #include <asm/imx-common/dma.h>
  #include <stdbool.h>
 -#ifdef CONFIG_VIDEO_IPUV3
 +#include <asm/arch/mxc_hdmi.h>
 +#include <asm/arch/crm_regs.h>
 +#include <asm/bootm.h>
 +#include <dm.h>
 +#include <imx_thermal.h>
++#include <div64.h>
+ #include <ipu.h>
 -#endif
+ DECLARE_GLOBAL_DATA_PTR;
++#define __data __attribute__((section(".data")))
++
+ #ifdef CONFIG_MX6_TEMPERATURE_MIN
+ #define TEMPERATURE_MIN                       CONFIG_MX6_TEMPERATURE_MIN
+ #else
+ #define TEMPERATURE_MIN                       (-40)
+ #endif
+ #ifdef CONFIG_MX6_TEMPERATURE_HOT
+ #define TEMPERATURE_HOT                       CONFIG_MX6_TEMPERATURE_HOT
+ #else
+ #define TEMPERATURE_HOT                       80
+ #endif
+ #ifdef CONFIG_MX6_TEMPERATURE_MAX
+ #define TEMPERATURE_MAX                       CONFIG_MX6_TEMPERATURE_MAX
+ #else
+ #define TEMPERATURE_MAX                       125
+ #endif
+ #define TEMP_AVG_COUNT                        5
+ #define TEMP_WARN_THRESHOLD           5
  
 -#define __data        __attribute__((section(".data")))
 +enum ldo_reg {
 +      LDO_ARM,
 +      LDO_SOC,
 +      LDO_PU,
 +};
  
  struct scu_regs {
        u32     ctrl;
        u32     fpga_rev;
  };
  
 -#ifdef CONFIG_HW_WATCHDOG
 -#define wdog_base     ((void *)WDOG1_BASE_ADDR)
 -#define WDOG_WCR      0x00
 -#define WCR_WDE               (1 << 2)
 -#define WDOG_WSR      0x02
 +#if defined(CONFIG_IMX6_THERMAL)
 +static const struct imx_thermal_plat imx6_thermal_plat = {
 +      .regs = (void *)ANATOP_BASE_ADDR,
 +      .fuse_bank = 1,
 +      .fuse_word = 6,
 +};
  
 -void hw_watchdog_reset(void)
 -{
 -      if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
 -              static u16 __data toggle = 0xaaaa;
 -              static int __data first = 1;
 +U_BOOT_DEVICE(imx6_thermal) = {
 +      .name = "imx_thermal",
 +      .platdata = &imx6_thermal_plat,
 +};
 +#endif
  
 -              if (first) {
 -                      printf("Watchdog active\n");
 -                      first = 0;
 -              }
 -              writew(toggle, wdog_base + WDOG_WSR);
 -              toggle ^= 0xffff;
 -      }
 +u32 get_nr_cpus(void)
 +{
 +      struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
 +      return readl(&scu->config) & 3;
  }
 -#endif
  
  u32 get_cpu_rev(void)
  {
  
        if (type != MXC_CPU_MX6SL) {
                reg = readl(&anatop->digprog);
 +              struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
 +              u32 cfg = readl(&scu->config) & 3;
                type = ((reg >> 16) & 0xff);
                if (type == MXC_CPU_MX6DL) {
 -                      struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
 -                      u32 cfg = readl(&scu->config) & 3;
 -
                        if (!cfg)
                                type = MXC_CPU_MX6SOLO;
                }
 +
 +              if (type == MXC_CPU_MX6Q) {
 +                      if (cfg == 1)
 +                              type = MXC_CPU_MX6D;
 +              }
 +
        }
        reg &= 0xff;            /* mx6 silicon revision */
        return (type << 12) | (reg + 0x10);
@@@ -92,9 -104,6 +118,9 @@@ u32 __weak get_board_rev(void
        if (type == MXC_CPU_MX6SOLO)
                cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
  
 +      if (type == MXC_CPU_MX6D)
 +              cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
 +
        return cpurev;
  }
  #endif
  void init_aips(void)
  {
        struct aipstz_regs *aips1, *aips2;
 +#ifdef CONFIG_MX6SX
 +      struct aipstz_regs *aips3;
 +#endif
  
        aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR;
        aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR;
 +#ifdef CONFIG_MX6SX
 +      aips3 = (struct aipstz_regs *)AIPS3_BASE_ADDR;
 +#endif
  
        /*
         * Set all MPROTx to be non-bufferable, trusted for R/W,
        writel(0x00000000, &aips2->opacr2);
        writel(0x00000000, &aips2->opacr3);
        writel(0x00000000, &aips2->opacr4);
 +
 +#ifdef CONFIG_MX6SX
 +      /*
 +       * Set all MPROTx to be non-bufferable, trusted for R/W,
 +       * not forced to user-mode.
 +       */
 +      writel(0x77777777, &aips3->mprot0);
 +      writel(0x77777777, &aips3->mprot1);
 +
 +      /*
 +       * Set all OPACRx to be non-bufferable, not require
 +       * supervisor privilege level for access,allow for
 +       * write access and untrusted master access.
 +       */
 +      writel(0x00000000, &aips3->opacr0);
 +      writel(0x00000000, &aips3->opacr1);
 +      writel(0x00000000, &aips3->opacr2);
 +      writel(0x00000000, &aips3->opacr3);
 +      writel(0x00000000, &aips3->opacr4);
 +#endif
 +}
 +
 +static void clear_ldo_ramp(void)
 +{
 +      struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 +      int reg;
 +
 +      /* ROM may modify LDO ramp up time according to fuse setting, so in
 +       * order to be in the safe side we neeed to reset these settings to
 +       * match the reset value: 0'b00
 +       */
 +      reg = readl(&anatop->ana_misc2);
 +      reg &= ~(0x3f << 24);
 +      writel(reg, &anatop->ana_misc2);
  }
  
  /*
 - * Set the VDDSOC
 + * Set the PMU_REG_CORE register
   *
 - * Mask out the REG_CORE[22:18] bits (REG2_TRIG) and set
 - * them to the specified millivolt level.
 + * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
   * Possible values are from 0.725V to 1.450V in steps of
   * 0.025V (25mV).
   */
 -static void set_vddsoc(u32 mv)
 +static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
  {
        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 -      u32 val, reg = readl(&anatop->reg_core);
 +      u32 val, step, old, reg = readl(&anatop->reg_core);
 +      u8 shift;
  
        if (mv < 725)
                val = 0x00;     /* Power gated off */
        else
                val = (mv - 700) / 25;
  
 +      clear_ldo_ramp();
 +
 +      switch (ldo) {
 +      case LDO_SOC:
 +              shift = 18;
 +              break;
 +      case LDO_PU:
 +              shift = 9;
 +              break;
 +      case LDO_ARM:
 +              shift = 0;
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      old = (reg & (0x1F << shift)) >> shift;
 +      step = abs(val - old);
 +      if (step == 0)
 +              return 0;
 +
 +      reg = (reg & ~(0x1F << shift)) | (val << shift);
 +      writel(reg, &anatop->reg_core);
 +
        /*
 -       * Mask out the REG_CORE[22:18] bits (REG2_TRIG)
 -       * and set them to the calculated value (0.7V + val * 0.25V)
 +       * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per
 +       * step
         */
 -      reg = (reg & ~(0x1F << 18)) | (val << 18);
 -      writel(reg, &anatop->reg_core);
 +      udelay(3 * step);
 +
 +      return 0;
  }
  
+ static u32 __data thermal_calib;
+ #define FACTOR0                               10000000
+ #define FACTOR1                               15976
+ #define FACTOR2                               4297157
+ int raw_to_celsius(unsigned int raw, unsigned int raw_25c, unsigned int raw_hot,
+               unsigned int hot_temp)
+ {
+       int temperature;
+       if (raw_hot != 0 && hot_temp != 0) {
+               unsigned int raw_n40c, ratio;
+               ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25);
+               raw_n40c = raw_25c + (13 * ratio) / 20;
+               if (raw <= raw_n40c)
+                       temperature = (raw_n40c - raw) * 100 / ratio - 40;
+               else
+                       temperature = TEMPERATURE_MIN;
+       } else {
+               u64 temp64 = FACTOR0;
+               unsigned int c1, c2;
+               /*
+                * Derived from linear interpolation:
+                * slope = 0.4297157 - (0.0015976 * 25C fuse)
+                * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
+                * (Nmeas - n1) / (Tmeas - t1) = slope
+                * We want to reduce this down to the minimum computation necessary
+                * for each temperature read.  Also, we want Tmeas in millicelsius
+                * and we don't want to lose precision from integer division. So...
+                * Tmeas = (Nmeas - n1) / slope + t1
+                * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
+                * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
+                * Let constant c1 = (-1000 / slope)
+                * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
+                * Let constant c2 = n1 *c1 + 1000 * t1
+                * milli_Tmeas = c2 - Nmeas * c1
+                */
+               temp64 *= 1000;
+               do_div(temp64, FACTOR1 * raw_25c - FACTOR2);
+               c1 = temp64;
+               c2 = raw_25c * c1 + 1000 * 25;
+               temperature = (c2 - raw * c1) / 1000;
+       }
+       return temperature;
+ }
+ int read_cpu_temperature(void)
+ {
+       unsigned int reg, tmp, i;
+       unsigned int raw_25c, raw_hot, hot_temp;
+       int temperature;
+       struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+       struct mx6_ocotp_regs *const ocotp_regs = (void *)OCOTP_BASE_ADDR;
+       if (!thermal_calib) {
+               ocotp_clk_enable();
+               writel(1, &ocotp_regs->hw_ocotp_read_ctrl);
+               thermal_calib = readl(&ocotp_regs->hw_ocotp_ana1);
+               writel(0, &ocotp_regs->hw_ocotp_read_ctrl);
+               ocotp_clk_disable();
+       }
+       if (thermal_calib == 0 || thermal_calib == 0xffffffff)
+               return TEMPERATURE_MIN;
+       /* Fuse data layout:
+        * [31:20] sensor value @ 25C
+        * [19:8] sensor value of hot
+        * [7:0] hot temperature value */
+       raw_25c = thermal_calib >> 20;
+       raw_hot = (thermal_calib & 0xfff00) >> 8;
+       hot_temp = thermal_calib & 0xff;
+       /* now we only using single measure, every time we measure
+        * the temperature, we will power on/off the anadig module
+        */
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
+       /* write measure freq */
+       writel(327, &anatop->tempsense1);
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
+       /* average the temperature value over multiple readings */
+       for (i = 0; i < TEMP_AVG_COUNT; i++) {
+               static int failed;
+               int limit = 100;
+               while ((readl(&anatop->tempsense0) &
+                               BM_ANADIG_TEMPSENSE0_FINISHED) == 0) {
+                       udelay(10000);
+                       if (--limit < 0)
+                               break;
+               }
+               if ((readl(&anatop->tempsense0) &
+                               BM_ANADIG_TEMPSENSE0_FINISHED) == 0) {
+                       if (!failed) {
+                               printf("Failed to read temp sensor\n");
+                               failed = 1;
+                       }
+                       return 0;
+               }
+               failed = 0;
+               reg = (readl(&anatop->tempsense0) &
+                       BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >>
+                       BP_ANADIG_TEMPSENSE0_TEMP_VALUE;
+               if (i == 0)
+                       tmp = reg;
+               else
+                       tmp = (tmp * i + reg) / (i + 1);
+               writel(BM_ANADIG_TEMPSENSE0_FINISHED,
+                       &anatop->tempsense0_clr);
+       }
+       temperature = raw_to_celsius(tmp, raw_25c, raw_hot, hot_temp);
+       /* power down anatop thermal sensor */
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
+       return temperature;
+ }
+ int check_cpu_temperature(int boot)
+ {
+       static int __data max_temp;
+       int boot_limit = getenv_ulong("max_boot_temp", 10, TEMPERATURE_HOT);
+       int tmp = read_cpu_temperature();
+       bool first = true;
+       if (tmp < TEMPERATURE_MIN || tmp > TEMPERATURE_MAX) {
+               printf("Temperature:   can't get valid data!\n");
+               return tmp;
+       }
+       if (!boot) {
+               if (tmp > boot_limit) {
+                       printf("CPU is %d C, too hot, resetting...\n", tmp);
+                       udelay(100000);
+                       reset_cpu(0);
+               }
+               if (tmp > max_temp) {
+                       if (tmp > boot_limit - TEMP_WARN_THRESHOLD)
+                               printf("WARNING: CPU temperature %d C\n", tmp);
+                       max_temp = tmp;
+               }
+       } else {
+               printf("Temperature:   %d C, calibration data 0x%x\n",
+                       tmp, thermal_calib);
+               while (tmp >= boot_limit) {
+                       if (first) {
+                               printf("CPU is %d C, too hot to boot, waiting...\n",
+                                       tmp);
+                               first = false;
+                       }
+                       if (ctrlc())
+                               break;
+                       udelay(50000);
+                       tmp = read_cpu_temperature();
+                       if (tmp > boot_limit - TEMP_WARN_THRESHOLD && tmp != max_temp)
+                               printf("WARNING: CPU temperature %d C\n", tmp);
+                       max_temp = tmp;
+               }
+       }
+       return tmp;
+ }
  static void imx_set_wdog_powerdown(bool enable)
  {
        struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
        writew(enable, &wdog2->wmcr);
  }
  
 -#ifdef CONFIG_ARCH_CPU_INIT
 +static void set_ahb_rate(u32 val)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      u32 reg, div;
 +
 +      div = get_periph_clk() / val - 1;
 +      reg = readl(&mxc_ccm->cbcdr);
 +
 +      writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
 +              (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
 +}
 +
 +static void clear_mmdc_ch_mask(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +
 +      /* Clear MMDC channel mask */
 +      writel(0, &mxc_ccm->ccdr);
 +}
 +
 +#ifdef CONFIG_MX6SL
 +static void set_preclk_from_osc(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      u32 reg;
 +
 +      reg = readl(&mxc_ccm->cscmr1);
 +      reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK;
 +      writel(reg, &mxc_ccm->cscmr1);
 +}
 +#endif
 +
  int arch_cpu_init(void)
  {
        init_aips();
  
 -      set_vddsoc(1200);       /* Set VDDSOC to 1.2V */
 +      /* Need to clear MMDC_CHx_MASK to make warm reset work. */
 +      clear_mmdc_ch_mask();
 +
 +      /*
 +       * When low freq boot is enabled, ROM will not set AHB
 +       * freq, so we need to ensure AHB freq is 132MHz in such
 +       * scenario.
 +       */
 +      if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
 +              set_ahb_rate(132000000);
 +
 +              /* Set perclk to source from OSC 24MHz */
 +#if defined(CONFIG_MX6SL)
 +      set_preclk_from_osc();
 +#endif
  
        imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
  
- #ifdef CONFIG_APBH_DMA
-       /* Start APBH DMA */
+ #ifdef CONFIG_VIDEO_IPUV3
+       gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3H;
+ #endif
+ #ifdef  CONFIG_APBH_DMA
+       /* Timer is required for Initializing APBH DMA */
+       timer_init();
        mxs_dma_init();
  #endif
 +
 +      return 0;
 +}
 +
 +int board_postclk_init(void)
 +{
 +      set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */
 +
        return 0;
  }
 -#endif
  
  #ifndef CONFIG_SYS_DCACHE_OFF
  void enable_caches(void)
  {
 +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
 +      enum dcache_option option = DCACHE_WRITETHROUGH;
 +#else
 +      enum dcache_option option = DCACHE_WRITEBACK;
 +#endif
 +
 +      /* Avoid random hang when download by usb */
 +      invalidate_dcache_all();
 +
        /* Enable D-cache. I-cache is already enabled in start.S */
        dcache_enable();
 +
 +      /* Enable caching on OCRAM and ROM */
 +      mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
 +                                      ROMCP_ARB_END_ADDR,
 +                                      option);
 +      mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
 +                                      IRAM_SIZE,
 +                                      option);
  }
  #endif
  
@@@ -339,14 -389,13 +540,13 @@@ void imx_get_mac_from_fuse(int dev_id, 
  
        u32 value = readl(&fuse->mac_addr_high);
        mac[0] = (value >> 8);
-       mac[1] = value ;
+       mac[1] = value;
  
        value = readl(&fuse->mac_addr_low);
-       mac[2] = value >> 24 ;
-       mac[3] = value >> 16 ;
-       mac[4] = value >> 8 ;
-       mac[5] = value ;
+       mac[2] = value >> 24;
+       mac[3] = value >> 16;
+       mac[4] = value >> 8;
+       mac[5] = value;
  }
  #endif
  
@@@ -365,18 -414,18 +565,18 @@@ void boot_mode_apply(unsigned cfg_val
  /*
   * cfg_val will be used for
   * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
 - * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
 - * to SBMR1, which will determine the boot device.
 + * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0]
 + * instead of SBMR1 to determine the boot device.
   */
  const struct boot_mode soc_boot_modes[] = {
        {"normal",      MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
        /* reserved value should start rom usb */
        {"usb",         MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)},
        {"sata",        MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
 -      {"escpi1:0",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
 -      {"escpi1:1",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
 -      {"escpi1:2",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
 -      {"escpi1:3",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
 +      {"ecspi1:0",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
 +      {"ecspi1:1",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
 +      {"ecspi1:2",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
 +      {"ecspi1:3",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
        /* 4 bit bus width */
        {"esdhc1",      MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
        {"esdhc2",      MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
  
  void s_init(void)
  {
 +      struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 +      struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      u32 mask480;
 +      u32 mask528;
 +      u32 reg, periph1, periph2;
 +
 +      if (is_cpu_type(MXC_CPU_MX6SX))
 +              return;
 +
 +      /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
 +       * to make sure PFD is working right, otherwise, PFDs may
 +       * not output clock after reset, MX6DL and MX6SL have added 396M pfd
 +       * workaround in ROM code, as bus clock need it
 +       */
 +
 +      mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
 +              ANATOP_PFD_CLKGATE_MASK(1) |
 +              ANATOP_PFD_CLKGATE_MASK(2) |
 +              ANATOP_PFD_CLKGATE_MASK(3);
 +      mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
 +              ANATOP_PFD_CLKGATE_MASK(3);
 +
 +      reg = readl(&ccm->cbcmr);
 +      periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
 +              >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
 +      periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
 +              >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
 +
 +      /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
 +      if ((periph2 != 0x2) && (periph1 != 0x2))
 +              mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
 +
 +      if ((periph2 != 0x1) && (periph1 != 0x1) &&
 +              (periph2 != 0x3) && (periph1 != 0x3))
 +              mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
 +
 +      writel(mask480, &anatop->pfd_480_set);
 +      writel(mask528, &anatop->pfd_528_set);
 +      writel(mask480, &anatop->pfd_480_clr);
 +      writel(mask528, &anatop->pfd_528_clr);
 +}
 +
 +#ifdef CONFIG_IMX_HDMI
 +void imx_enable_hdmi_phy(void)
 +{
 +      struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 +      u8 reg;
 +      reg = readb(&hdmi->phy_conf0);
 +      reg |= HDMI_PHY_CONF0_PDZ_MASK;
 +      writeb(reg, &hdmi->phy_conf0);
 +      udelay(3000);
 +      reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
 +      writeb(reg, &hdmi->phy_conf0);
 +      udelay(3000);
 +      reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
 +      writeb(reg, &hdmi->phy_conf0);
 +      writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
 +}
 +
 +void imx_setup_hdmi(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 +      int reg;
 +
 +      /* Turn on HDMI PHY clock */
 +      reg = readl(&mxc_ccm->CCGR2);
 +      reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
 +               MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
 +      writel(reg, &mxc_ccm->CCGR2);
 +      writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
 +      reg = readl(&mxc_ccm->chsccdr);
 +      reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
 +               MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
 +               MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
 +      reg |= (CHSCCDR_PODF_DIVIDE_BY_3
 +               << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 +               |(CHSCCDR_IPU_PRE_CLK_540M_PFD
 +               << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 +      writel(reg, &mxc_ccm->chsccdr);
 +}
 +#endif
 +
 +#ifndef CONFIG_SYS_L2CACHE_OFF
 +#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
 +void v7_outer_cache_enable(void)
 +{
 +      struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 +      unsigned int val;
 +
 +#if defined CONFIG_MX6SL
 +      struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 +      val = readl(&iomux->gpr[11]);
 +      if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
 +              /* L2 cache configured as OCRAM, reset it */
 +              val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
 +              writel(val, &iomux->gpr[11]);
 +      }
 +#endif
 +
 +      /* Must disable the L2 before changing the latency parameters */
 +      clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 +
 +      writel(0x132, &pl310->pl310_tag_latency_ctrl);
 +      writel(0x132, &pl310->pl310_data_latency_ctrl);
 +
 +      val = readl(&pl310->pl310_prefetch_ctrl);
 +
 +      /* Turn on the L2 I/D prefetch */
 +      val |= 0x30000000;
 +
 +      /*
 +       * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
 +       * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
 +       * But according to ARM PL310 errata: 752271
 +       * ID: 752271: Double linefill feature can cause data corruption
 +       * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
 +       * Workaround: The only workaround to this erratum is to disable the
 +       * double linefill feature. This is the default behavior.
 +       */
 +
 +#ifndef CONFIG_MX6Q
 +      val |= 0x40800000;
 +#endif
 +      writel(val, &pl310->pl310_prefetch_ctrl);
 +
 +      val = readl(&pl310->pl310_power_ctrl);
 +      val |= L2X0_DYNAMIC_CLK_GATING_EN;
 +      val |= L2X0_STNDBY_MODE_EN;
 +      writel(val, &pl310->pl310_power_ctrl);
 +
 +      setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 +}
 +
 +void v7_outer_cache_disable(void)
 +{
 +      struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 +
 +      clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
  }
 +#endif /* !CONFIG_SYS_L2CACHE_OFF */
index 00a108212a7294c40e26ee0e12056a19510b3b0c,ad383872c57f706a65a8171c756c2b815e92a194..fdef7a708fb6c44f13336c79093bf8aa90dc4ef0
@@@ -9,14 -9,11 +9,14 @@@
   */
  
  #include <common.h>
 +#include <ahci.h>
  #include <spl.h>
  #include <asm/omap_common.h>
  #include <asm/arch/omap.h>
  #include <asm/arch/mmc_host_def.h>
  #include <asm/arch/sys_proto.h>
 +#include <watchdog.h>
 +#include <scsi.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
@@@ -35,27 -32,15 +35,27 @@@ void save_omap_boot_params(void
         * used. But it not correct to assume that romcode structure
         * encoding would be same as u-boot. So use the defined offsets.
         */
 -      gd->arch.omap_boot_params.omap_bootdevice = boot_device =
 -                                 *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
 +      boot_device = *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
 +
 +#if defined(BOOT_DEVICE_NAND_I2C)
 +      /*
 +       * Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
 +       * Otherwise the SPL boot IF can't handle this device correctly.
 +       * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens
 +       * Draco leads to this boot-device passed to SPL from the BootROM.
 +       */
 +      if (boot_device == BOOT_DEVICE_NAND_I2C)
 +              boot_device = BOOT_DEVICE_NAND;
 +#endif
 +      gd->arch.omap_boot_params.omap_bootdevice = boot_device;
  
        gd->arch.omap_boot_params.ch_flags =
                                *((u8 *)(rom_params + CH_FLAGS_OFFSET));
  
        if ((boot_device >= MMC_BOOT_DEVICES_START) &&
            (boot_device <= MMC_BOOT_DEVICES_END)) {
 -#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX)
 +#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX) && \
 +      !defined(CONFIG_AM43XX)
                if ((omap_hw_init_context() ==
                                      OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
                        gd->arch.omap_boot_params.omap_bootmode =
                                        *((u32 *)(dev_data + BOOT_MODE_OFFSET));
                }
        }
 +
 +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
 +      /*
 +       * We get different values for QSPI_1 and QSPI_4 being used, but
 +       * don't actually care about this difference.  Rather than
 +       * mangle the later code, if we're coming in as QSPI_4 just
 +       * change to the QSPI_1 value.
 +       */
 +      if (gd->arch.omap_boot_params.omap_bootdevice == 11)
 +              gd->arch.omap_boot_params.omap_bootdevice = BOOT_DEVICE_SPI;
 +#endif
  }
  
  #ifdef CONFIG_SPL_BUILD
  u32 spl_boot_device(void)
  {
-       return (u32) (gd->arch.omap_boot_params.omap_bootdevice);
+       return gd->arch.omap_boot_params.omap_bootdevice;
  }
  
  u32 spl_boot_mode(void)
  {
 -      return gd->arch.omap_boot_params.omap_bootmode;
 +      u32 val = gd->arch.omap_boot_params.omap_bootmode;
 +
 +      if (val == MMCSD_MODE_RAW)
 +              return MMCSD_MODE_RAW;
 +      else if (val == MMCSD_MODE_FS)
 +              return MMCSD_MODE_FS;
 +      else
 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
 +              return MMCSD_MODE_EMMCBOOT;
 +#else
 +              return MMCSD_MODE_UNDEFINED;
 +#endif
  }
  
  void spl_board_init(void)
  #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
        arch_misc_init();
  #endif
 +#if defined(CONFIG_HW_WATCHDOG)
 +      hw_watchdog_init();
 +#endif
 +#ifdef CONFIG_AM33XX
 +      am33xx_spl_board_init();
 +#endif
  }
  
  int board_mmc_init(bd_t *bis)
@@@ -145,10 -102,3 +145,10 @@@ void __noreturn jump_to_image_no_args(s
        image_entry((u32 *)&gd->arch.omap_boot_params);
  }
  #endif
 +
 +#ifdef CONFIG_SCSI_AHCI_PLAT
 +void arch_preboot_os(void)
 +{
 +      ahci_reset(DWC_AHSATA_BASE);
 +}
 +#endif
index e88e6e2a9881d0dcd00af5477453afe219ed79b1,fe43d872ddc715b2c36d5a4fbec0a497ee8d563a..b96104c0cc9f6116aab84dd9cf35d337ac9a6fba
@@@ -11,9 -11,6 +11,9 @@@
  #include <common.h>
  #include <asm/io.h>
  #include <asm/arch/imx-regs.h>
 +#if !defined(CONFIG_MX25) && !defined(CONFIG_VF610)
 +#include <asm/arch/sys_proto.h>
 +#endif
  #include <asm/imx-common/iomux-v3.h>
  
  static void *base = (void *)IOMUXC_BASE_ADDR;
@@@ -33,14 -30,6 +33,19 @@@ void imx_iomux_v3_setup_pad(iomux_v3_cf
                (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
        u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
  
 +#if defined CONFIG_MX6SL
 +      /* Check whether LVE bit needs to be set */
 +      if (pad_ctrl & PAD_CTL_LVE) {
 +              pad_ctrl &= ~PAD_CTL_LVE;
 +              pad_ctrl |= PAD_CTL_LVE_BIT;
 +      }
 +#endif
++#ifdef DEBUG
++      printf("PAD[%2d]=%016llx mux[%03x]=%02x pad[%03x]=%05x%c inp[%03x]=%d\n",
++              i, pad, mux_ctrl_ofs, mux_mode, pad_ctrl_ofs, pad_ctrl,
++              pad & PAD_CTRL_VALID ? ' ' : '!', sel_input_ofs, sel_input);
++#endif
 +
        if (mux_ctrl_ofs)
                __raw_writel(mux_mode, base + mux_ctrl_ofs);
  
                __raw_writel(sel_input, base + sel_input_ofs);
  
  #ifdef CONFIG_IOMUX_SHARE_CONF_REG
-       if (!(pad_ctrl & NO_PAD_CTRL))
+       if (pad & PAD_CTRL_VALID)
                __raw_writel((mux_mode << PAD_MUX_MODE_SHIFT) | pad_ctrl,
                        base + pad_ctrl_ofs);
  #else
-       if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+       if ((pad & PAD_CTRL_VALID) && pad_ctrl_ofs)
                __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
  #endif
  }
  
 +/* configures a list of pads within declared with IOMUX_PADS macro */
  void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
                                      unsigned count)
  {
        iomux_v3_cfg_t const *p = pad_list;
 +      int stride;
        int i;
  
 -      for (i = 0; i < count; i++) {
 -#ifdef DEBUG
 -              u32 mux_ctrl_ofs = (*p & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
 -              u32 mux_mode = (*p & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
 -              u32 sel_input_ofs =
 -                      (*p & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
 -              u32 sel_input =
 -                      (*p & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
 -              u32 pad_ctrl_ofs =
 -                      (*p & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
 -              u32 pad_ctrl = (*p & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
 -
 -              printf("PAD[%2d]=%016llx mux[%03x]=%02x pad[%03x]=%05x%c inp[%03x]=%d\n",
 -                      i, *p, mux_ctrl_ofs, mux_mode, pad_ctrl_ofs, pad_ctrl,
 -                      *p & PAD_CTRL_VALID ? ' ' : '!', sel_input_ofs, sel_input);
 +#if defined(CONFIG_MX6QDL)
 +      stride = 2;
 +      if (!is_cpu_type(MXC_CPU_MX6Q) && !is_cpu_type(MXC_CPU_MX6D))
 +              p += 1;
 +#else
 +      stride = 1;
  #endif
 -              imx_iomux_v3_setup_pad(*p++);
 +      for (i = 0; i < count; i++) {
 +              imx_iomux_v3_setup_pad(*p);
 +              p += stride;
        }
  }
-                                       int num_bits, int value)
 +
 +void imx_iomux_set_gpr_register(int group, int start_bit,
-       int i = 0;
-       u32 reg;
-       reg = readl(base + group * 4);
-       while (num_bits) {
-               reg &= ~(1<<(start_bit + i));
-               i++;
-               num_bits--;
-       }
-       reg |= (value << start_bit);
++                              int num_bits, int value)
 +{
++      u32 reg = readl(base + group * 4);
++
++      reg &= ~(((1 << num_bits) - 1) << start_bit);
++      reg |= value << start_bit;
 +      writel(reg, base + group * 4);
 +}
index 65ef60bf2edb0a115d7bc48b1eb35dffa0b41901,92712a6de55b86a2432bbbf02ac694566b2c3b68..1da931ab0f4a761d5e6d39eaa27910876fc7db9e
@@@ -12,7 -12,6 +12,7 @@@
  #include <div64.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/clock.h>
 +#include <asm/arch/sys_proto.h>
  
  /* General purpose timers registers */
  struct mxc_gpt {
@@@ -27,59 -26,31 +27,68 @@@ static struct mxc_gpt *cur_gpt = (struc
  
  /* General purpose timers bitfields */
  #define GPTCR_SWR             (1 << 15)       /* Software reset */
 +#define GPTCR_24MEN       (1 << 10)   /* Enable 24MHz clock input */
  #define GPTCR_FRR             (1 << 9)        /* Freerun / restart */
 -#define GPTCR_CLKSOURCE_32    (4 << 6)        /* Clock source */
 +#define GPTCR_CLKSOURCE_32    (4 << 6)        /* Clock source 32khz */
 +#define GPTCR_CLKSOURCE_OSC   (5 << 6)        /* Clock source OSC */
 +#define GPTCR_CLKSOURCE_PRE   (1 << 6)        /* Clock source PRECLK */
 +#define GPTCR_CLKSOURCE_MASK (0x7 << 6)
  #define GPTCR_TEN             1               /* Timer enable */
  
 +#define GPTPR_PRESCALER24M_SHIFT 12
 +#define GPTPR_PRESCALER24M_MASK (0xF << GPTPR_PRESCALER24M_SHIFT)
 +
  DECLARE_GLOBAL_DATA_PTR;
  
 +static inline int gpt_has_clk_source_osc(void)
 +{
 +#if defined(CONFIG_MX6)
 +      if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) &&
 +           (is_soc_rev(CHIP_REV_1_0) > 0)) || is_cpu_type(MXC_CPU_MX6DL) ||
 +            is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX))
 +              return 1;
 +
 +      return 0;
 +#else
 +      return 0;
 +#endif
 +}
 +
 +static inline ulong gpt_get_clk(void)
 +{
 +#ifdef CONFIG_MXC_GPT_HCLK
 +      if (gpt_has_clk_source_osc())
 +              return MXC_HCLK >> 3;
 +      else
 +              return mxc_get_clock(MXC_IPG_PERCLK);
 +#else
 +      return MXC_CLK32;
 +#endif
 +}
  static inline unsigned long long tick_to_time(unsigned long long tick)
  {
 +      ulong gpt_clk = gpt_get_clk();
 +
        tick *= CONFIG_SYS_HZ;
 -      do_div(tick, MXC_CLK32);
 +      do_div(tick, gpt_clk);
 +
        return tick;
  }
  
+ static inline unsigned long time_to_tick(unsigned long time)
+ {
+       unsigned long long ticks = (unsigned long long)time;
+       ticks *= MXC_CLK32;
+       do_div(ticks, CONFIG_SYS_HZ);
+       return ticks;
+ }
  static inline unsigned long long us_to_tick(unsigned long long usec)
  {
 -      usec = usec * MXC_CLK32 + 999999;
 +      ulong gpt_clk = gpt_get_clk();
 +
 +      usec = usec * gpt_clk + 999999;
        do_div(usec, 1000000);
  
        return usec;
@@@ -96,35 -67,16 +105,36 @@@ int timer_init(void
        for (i = 0; i < 100; i++)
                __raw_writel(0, &cur_gpt->control);
  
 -      __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
 -
 -      /* Freerun Mode, PERCLK1 input */
        i = __raw_readl(&cur_gpt->control);
 -      __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
 +      i &= ~GPTCR_CLKSOURCE_MASK;
 +
 +#ifdef CONFIG_MXC_GPT_HCLK
 +      if (gpt_has_clk_source_osc()) {
 +              i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN;
 +
 +              /* For DL/S, SX, set 24Mhz OSC Enable bit and prescaler */
 +              if (is_cpu_type(MXC_CPU_MX6DL) ||
 +                  is_cpu_type(MXC_CPU_MX6SOLO) ||
 +                  is_cpu_type(MXC_CPU_MX6SX)) {
 +                      i |= GPTCR_24MEN;
 +
 +                      /* Produce 3Mhz clock */
 +                      __raw_writel((7 << GPTPR_PRESCALER24M_SHIFT),
 +                                   &cur_gpt->prescaler);
 +              }
 +      } else {
 +              i |= GPTCR_CLKSOURCE_PRE | GPTCR_TEN;
 +      }
 +#else
 +      __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
 +      i |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
 +#endif
 +      __raw_writel(i, &cur_gpt->control);
  
        gd->arch.tbl = __raw_readl(&cur_gpt->counter);
        gd->arch.tbu = 0;
  
+       gd->arch.timer_rate_hz = MXC_CLK32;
        return 0;
  }
  
@@@ -143,29 -95,40 +153,40 @@@ ulong get_timer_masked(void
  {
        /*
         * get_ticks() returns a long long (64 bit), it wraps in
 -       * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
 +       * 2^64 / GPT_CLK = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
         * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
         * 5 * 10^6 days - long enough.
         */
+       /*
+        * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
+        * Thus the calculation above is not true.
+        * A 64bit timer value would only make sense if it was
+        * consistently used throughout the code. Thus also the parameter
+        * to get_timer() and its return value would need to be 64bit wide!
+        */
        return tick_to_time(get_ticks());
  }
  
  ulong get_timer(ulong base)
  {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
  }
  
  /* delay x useconds AND preserve advance timstamp value */
  void __udelay(unsigned long usec)
  {
-       unsigned long long tmp;
-       ulong tmo;
+       unsigned long start = __raw_readl(&cur_gpt->counter);
+       unsigned long ticks;
+       if (usec == 0)
+               return;
  
-       tmo = us_to_tick(usec);
-       tmp = get_ticks() + tmo;        /* get current timestamp */
+       ticks = us_to_tick(usec);
+       if (ticks == 0)
+               ticks++;
  
-       while (get_ticks() < tmp)       /* loop till event */
-                /*NOP*/;
+       while (__raw_readl(&cur_gpt->counter) - start < ticks)
+               /* loop till event */;
  }
  
  /*
   */
  ulong get_tbclk(void)
  {
 -      return gd->arch.timer_rate_hz;
 +      return gpt_get_clk();
  }
index 4c9352a2ed768f29bcec1ff5678807ccbb396464,29b0964bdf16681efa5ca1bbd0514834c39d7ff1..5657f1846a30614fef2343d20fb608010e4ce751
  #ifndef _CLOCKS_AM33XX_H_
  #define _CLOCKS_AM33XX_H_
  
 +/* MAIN PLL Fdll supported frequencies */
 +#define MPUPLL_M_1000 1000
 +#define MPUPLL_M_800  800
 +#define MPUPLL_M_720  720
 +#define MPUPLL_M_600  600
 +#define MPUPLL_M_550  550
 +#define MPUPLL_M_300  300
 +
  /* MAIN PLL Fdll = 550 MHz, by default */
  #ifndef CONFIG_SYS_MPUCLK
 -#define CONFIG_SYS_MPUCLK     550
 +#define CONFIG_SYS_MPUCLK     MPUPLL_M_550
  #endif
  
 -extern void pll_init(void);
 -extern void enable_emif_clocks(void);
+ #define DISPPLL_M     200
+ #define DISPPLL_N     (OSC - 1)
+ #define DISPPLL_M2    1
 +#define UART_RESET            (0x1 << 1)
 +#define UART_CLK_RUNNING_MASK 0x1
 +#define UART_SMART_IDLE_EN    (0x1 << 0x3)
 +
 +#define CM_DLL_CTRL_NO_OVERRIDE       0x0
 +#define CM_DLL_READYST                0x4
 +
  extern void enable_dmm_clocks(void);
 +extern const struct dpll_params dpll_core_opp100;
 +extern struct dpll_params dpll_mpu_opp100;
  
  #endif        /* endif _CLOCKS_AM33XX_H_ */
index 8dd69b3c80ee3022cb657720f217b3aaf8eb4568,0319269b5839bb77b2401bb4392a596e5e4a629b..9367a707d3f0c966136ded10129908b60097ad7d
  
  #include <asm/arch/hardware.h>
  
- #define BIT(x)                                (1 << x)
- #define CL_BIT(x)                     (0 << x)
+ #define BIT(x)                                (1 << (x))
+ #define CL_BIT(x)                     (0 << (x))
  
  /* Timer register bits */
  #define TCLR_ST                               BIT(0)  /* Start=1 Stop=0 */
  #define TCLR_AR                               BIT(1)  /* Auto reload */
  #define TCLR_PRE                      BIT(5)  /* Pre-scaler enable */
- #define TCLR_PTV_SHIFT                        (2)     /* Pre-scaler shift value */
+ #define TCLR_PTV_SHIFT                        2       /* Pre-scaler shift value */
  #define TCLR_PRE_DISABLE              CL_BIT(5) /* Pre-scalar disable */
 +#define TCLR_CE                               BIT(6)  /* compare mode enable */
 +#define TCLR_SCPWM                    BIT(7)  /* pwm outpin behaviour */
 +#define TCLR_TCM                      BIT(8)  /* edge detection of input pin*/
 +#define TCLR_TRG_SHIFT                        (10)    /* trigmode on pwm outpin */
 +#define TCLR_PT                               BIT(12) /* pulse/toggle mode of outpin*/
 +#define TCLR_CAPTMODE                 BIT(13) /* capture mode */
 +#define TCLR_GPOCFG                   BIT(14) /* 0=output,1=input */
  
 +#define TCFG_RESET                    BIT(0)  /* software reset */
 +#define TCFG_EMUFREE                  BIT(1)  /* behaviour of tmr on debug */
 +#define TCFG_IDLEMOD_SHIFT            (2)     /* power management */
  /* device type */
  #define DEVICE_MASK                   (BIT(8) | BIT(9) | BIT(10))
  #define TST_DEVICE                    0x0
  #define AM335X                                0xB944
  #define TI81XX                                0xB81E
  #define DEVICE_ID                     (CTRL_BASE + 0x0600)
 +#define DEVICE_ID_MASK                        0x1FFF
 +
 +/* MPU max frequencies */
 +#define AM335X_ZCZ_300                        0x1FEF
 +#define AM335X_ZCZ_600                        0x1FAF
 +#define AM335X_ZCZ_720                        0x1F2F
 +#define AM335X_ZCZ_800                        0x1E2F
 +#define AM335X_ZCZ_1000                       0x1C2F
 +#define AM335X_ZCE_300                        0x1FDF
 +#define AM335X_ZCE_600                        0x1F9F
  
  /* This gives the status of the boot mode pins on the evm */
- #define SYSBOOT_MASK                  (BIT(0) | BIT(1) | BIT(2)\
-                                       | BIT(3) | BIT(4))
+ #define SYSBOOT_MASK                  (BIT(0) | BIT(1) | BIT(2) | \
+                                               BIT(3) | BIT(4))
  
 -/* Reset control */
 -#ifdef CONFIG_AM33XX
 -#define PRM_RSTCTRL                   (PRCM_BASE + 0x0F00)
 -#elif defined(CONFIG_TI814X)
 -#define PRM_RSTCTRL                   (PRCM_BASE + 0x00A0)
 -#endif
 -#define PRM_RSTST                     (PRM_RSTCTRL + 8)
  #define PRM_RSTCTRL_RESET             0x01
  #define PRM_RSTST_WARM_RESET_MASK     0x232
  
 +/*
 + * Watchdog:
 + * Using the prescaler, the OMAP watchdog could go for many
 + * months before firing.  These limits work without scaling,
 + * with the 60 second default assumed by most tools and docs.
 + */
 +#define TIMER_MARGIN_MAX      (24 * 60 * 60)  /* 1 day */
 +#define TIMER_MARGIN_DEFAULT  60      /* 60 secs */
 +#define TIMER_MARGIN_MIN      1
 +
 +#define PTV                   0       /* prescale */
 +#define GET_WLDR_VAL(secs)    (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
 +#define WDT_WWPS_PEND_WCLR    BIT(0)
 +#define WDT_WWPS_PEND_WLDR    BIT(2)
 +#define WDT_WWPS_PEND_WTGR    BIT(3)
 +#define WDT_WWPS_PEND_WSPR    BIT(4)
 +
 +#define WDT_WCLR_PRE          BIT(5)
 +#define WDT_WCLR_PTV_OFF      2
 +
  #ifndef __KERNEL_STRICT_NAMES
  #ifndef __ASSEMBLY__
 -struct gpmc_cs {
 -      u32 config1;            /* 0x00 */
 -      u32 config2;            /* 0x04 */
 -      u32 config3;            /* 0x08 */
 -      u32 config4;            /* 0x0C */
 -      u32 config5;            /* 0x10 */
 -      u32 config6;            /* 0x14 */
 -      u32 config7;            /* 0x18 */
 -      u32 nand_cmd;           /* 0x1C */
 -      u32 nand_adr;           /* 0x20 */
 -      u32 nand_dat;           /* 0x24 */
 -      u8 res[8];              /* blow up to 0x30 byte */
 -};
 -
 -struct bch_res_0_3 {
 -      u32 bch_result_x[4];
 -};
  
 -struct gpmc {
 -      u32 res1[4];
 -      u32 sysconfig;          /* 0x10 */
 -      u32 res2;
 -      u32 irqstatus;          /* 0x18 */
 -      u32 irqenable;          /* 0x1C */
 -      u32 res3[8];
 -      u32 timeout_control;    /* 0x40 */
 -      u32 res4[3];
 -      u32 config;             /* 0x50 */
 -      u32 status;             /* 0x54 */
 -      u32 res5[2];            /* 0x58 */
 -      struct gpmc_cs cs[8];   /* 0x60, 0x90, .. */
 -      u32 pref_config1;       /* 0x1E0 */
 -      u32 pref_config2;       /* 0x1E4 */
 -      u32 res6;               /* 0x1E8 */
 -      u32 pref_control;       /* 0x1EC */
 -      u32 pref_status;        /* 0x1F0 */
 -      u32 ecc_config;         /* 0x1F4 */
 -      u32 ecc_control;        /* 0x1F8 */
 -      u32 ecc_size_config;    /* 0x1FC */
 -      u32 ecc1_result;        /* 0x200 */
 -      u32 ecc2_result;        /* 0x204 */
 -      u32 ecc3_result;        /* 0x208 */
 -      u32 ecc4_result;        /* 0x20C */
 -      u32 ecc5_result;        /* 0x210 */
 -      u32 ecc6_result;        /* 0x214 */
 -      u32 ecc7_result;        /* 0x218 */
 -      u32 ecc8_result;        /* 0x21C */
 -      u32 ecc9_result;        /* 0x220 */
 -      u32 res7[3];            /* 0x224 */
 -      u32 testmomde_ctrl;     /* 0x230 */
 -      u32 res8[3];            /* 0x234 */
 -      struct bch_res_0_3 bch_result_0_3[2];   /* 0x240 */
 -};
  
 +#ifndef CONFIG_AM43XX
  /* Encapsulating core pll registers */
  struct cm_wkuppll {
        unsigned int wkclkstctrl;       /* offset 0x00 */
        unsigned int wkctrlclkctrl;     /* offset 0x04 */
        unsigned int wkgpio0clkctrl;    /* offset 0x08 */
        unsigned int wkl4wkclkctrl;     /* offset 0x0c */
 -      unsigned int resv2[4];
 +      unsigned int timer0clkctrl;     /* offset 0x10 */
 +      unsigned int resv2[3];
        unsigned int idlestdpllmpu;     /* offset 0x20 */
        unsigned int resv3[2];
        unsigned int clkseldpllmpu;     /* offset 0x2c */
        unsigned int idlestdpllddr;     /* offset 0x34 */
        unsigned int resv5[2];
        unsigned int clkseldpllddr;     /* offset 0x40 */
-       unsigned int resv6[4];
+       unsigned int autoidledplldisp;  /* offset 0x44 */
+       unsigned int idlestdplldisp;    /* offset 0x48 */
+       unsigned int resv6[2];
        unsigned int clkseldplldisp;    /* offset 0x54 */
        unsigned int resv7[1];
        unsigned int idlestdpllcore;    /* offset 0x5c */
        unsigned int resv11[1];
        unsigned int wkup_uart0ctrl;    /* offset 0xB4 */
        unsigned int wkup_i2c0ctrl;     /* offset 0xB8 */
 -      unsigned int resv12[6];
 -      unsigned int wdtimer1ctrl;
 +      unsigned int wkup_adctscctrl;   /* offset 0xBC */
 +      unsigned int resv12;
 +      unsigned int timer1clkctrl;     /* offset 0xC4 */
 +      unsigned int resv13[4];
        unsigned int divm6dpllcore;     /* offset 0xD8 */
  };
  
@@@ -150,7 -167,7 +152,7 @@@ struct cm_perpll 
        unsigned int resv1;
        unsigned int cpgmac0clkctrl;    /* offset 0x14 */
        unsigned int lcdclkctrl;        /* offset 0x18 */
-       unsigned int usb0clkctrl;       /* offset 0x1C */
+       unsigned int usb0clkctrl;       /* offset 0x1c */
        unsigned int resv2;
        unsigned int tptc0clkctrl;      /* offset 0x24 */
        unsigned int emifclkctrl;       /* offset 0x28 */
        unsigned int tpccclkctrl;       /* offset 0xBC */
        unsigned int dcan0clkctrl;      /* offset 0xC0 */
        unsigned int dcan1clkctrl;      /* offset 0xC4 */
 -      unsigned int resv6[2];
 +      unsigned int resv6;
 +      unsigned int epwmss1clkctrl;    /* offset 0xCC */
        unsigned int emiffwclkctrl;     /* offset 0xD0 */
 -      unsigned int resv7[2];
 +      unsigned int epwmss0clkctrl;    /* offset 0xD4 */
 +      unsigned int epwmss2clkctrl;    /* offset 0xD8 */
        unsigned int l3instrclkctrl;    /* offset 0xDC */
        unsigned int l3clkctrl;         /* Offset 0xE0 */
 -      unsigned int resv8[4];
 +      unsigned int resv8[2];
 +      unsigned int timer5clkctrl;     /* offset 0xEC */
 +      unsigned int timer6clkctrl;     /* offset 0xF0 */
        unsigned int mmc1clkctrl;       /* offset 0xF4 */
        unsigned int mmc2clkctrl;       /* offset 0xF8 */
        unsigned int resv9[8];
        unsigned int l4hsclkctrl;       /* offset 0x120 */
        unsigned int resv10[8];
        unsigned int cpswclkstctrl;     /* offset 0x144 */
 +      unsigned int lcdcclkstctrl;     /* offset 0x148 */
  };
  
  /* Encapsulating Display pll registers */
  struct cm_dpll {
 -      unsigned int resv1[2];
 +      unsigned int resv1;
 +      unsigned int clktimer7clk;      /* offset 0x04 */
        unsigned int clktimer2clk;      /* offset 0x08 */
 +      unsigned int clktimer3clk;      /* offset 0x0C */
 +      unsigned int clktimer4clk;      /* offset 0x10 */
 +      unsigned int resv2;
 +      unsigned int clktimer5clk;      /* offset 0x18 */
 +      unsigned int clktimer6clk;      /* offset 0x1C */
 +      unsigned int resv3[2];
 +      unsigned int clktimer1clk;      /* offset 0x28 */
 +      unsigned int resv4[2];
 +      unsigned int clklcdcpixelclk;   /* offset 0x34 */
 +};
 +#else
 +/* Encapsulating core pll registers */
 +struct cm_wkuppll {
 +      unsigned int resv0[136];
 +      unsigned int wkl4wkclkctrl;     /* offset 0x220 */
 +      unsigned int resv1[55];
 +      unsigned int wkclkstctrl;       /* offset 0x300 */
 +      unsigned int resv2[15];
 +      unsigned int wkup_i2c0ctrl;     /* offset 0x340 */
 +      unsigned int resv3;
 +      unsigned int wkup_uart0ctrl;    /* offset 0x348 */
 +      unsigned int resv4[5];
 +      unsigned int wkctrlclkctrl;     /* offset 0x360 */
 +      unsigned int resv5;
 +      unsigned int wkgpio0clkctrl;    /* offset 0x368 */
 +
 +      unsigned int resv6[109];
 +      unsigned int clkmoddpllcore;    /* offset 0x520 */
 +      unsigned int idlestdpllcore;    /* offset 0x524 */
 +      unsigned int resv61;
 +      unsigned int clkseldpllcore;    /* offset 0x52C */
 +      unsigned int resv7[2];
 +      unsigned int divm4dpllcore;     /* offset 0x538 */
 +      unsigned int divm5dpllcore;     /* offset 0x53C */
 +      unsigned int divm6dpllcore;     /* offset 0x540 */
 +
 +      unsigned int resv8[7];
 +      unsigned int clkmoddpllmpu;     /* offset 0x560 */
 +      unsigned int idlestdpllmpu;     /* offset 0x564 */
 +      unsigned int resv9;
 +      unsigned int clkseldpllmpu;     /* offset 0x56c */
 +      unsigned int divm2dpllmpu;      /* offset 0x570 */
 +
 +      unsigned int resv10[11];
 +      unsigned int clkmoddpllddr;     /* offset 0x5A0 */
 +      unsigned int idlestdpllddr;     /* offset 0x5A4 */
 +      unsigned int resv11;
 +      unsigned int clkseldpllddr;     /* offset 0x5AC */
 +      unsigned int divm2dpllddr;      /* offset 0x5B0 */
 +
 +      unsigned int resv12[11];
 +      unsigned int clkmoddpllper;     /* offset 0x5E0 */
 +      unsigned int idlestdpllper;     /* offset 0x5E4 */
 +      unsigned int resv13;
 +      unsigned int clkseldpllper;     /* offset 0x5EC */
 +      unsigned int divm2dpllper;      /* offset 0x5F0 */
 +      unsigned int resv14[8];
 +      unsigned int clkdcoldodpllper;  /* offset 0x614 */
 +
 +      unsigned int resv15[2];
 +      unsigned int clkmoddplldisp;    /* offset 0x620 */
 +      unsigned int resv16[2];
 +      unsigned int clkseldplldisp;    /* offset 0x62C */
 +      unsigned int divm2dplldisp;     /* offset 0x630 */
  };
  
 +/*
 + * Encapsulating peripheral functional clocks
 + * pll registers
 + */
 +struct cm_perpll {
 +      unsigned int l3clkstctrl;       /* offset 0x00 */
 +      unsigned int resv0[7];
 +      unsigned int l3clkctrl;         /* Offset 0x20 */
 +      unsigned int resv1[7];
 +      unsigned int l3instrclkctrl;    /* offset 0x40 */
 +      unsigned int resv2[3];
 +      unsigned int ocmcramclkctrl;    /* offset 0x50 */
 +      unsigned int resv3[9];
 +      unsigned int tpccclkctrl;       /* offset 0x78 */
 +      unsigned int resv4;
 +      unsigned int tptc0clkctrl;      /* offset 0x80 */
 +
 +      unsigned int resv5[7];
 +      unsigned int l4hsclkctrl;       /* offset 0x0A0 */
 +      unsigned int resv6;
 +      unsigned int l4fwclkctrl;       /* offset 0x0A8 */
 +      unsigned int resv7[85];
 +      unsigned int l3sclkstctrl;      /* offset 0x200 */
 +      unsigned int resv8[7];
 +      unsigned int gpmcclkctrl;       /* offset 0x220 */
 +      unsigned int resv9[5];
 +      unsigned int mcasp0clkctrl;     /* offset 0x238 */
 +      unsigned int resv10;
 +      unsigned int mcasp1clkctrl;     /* offset 0x240 */
 +      unsigned int resv11;
 +      unsigned int mmc2clkctrl;       /* offset 0x248 */
 +      unsigned int resv12[3];
 +      unsigned int qspiclkctrl;       /* offset 0x258 */
 +      unsigned int resv121;
 +      unsigned int usb0clkctrl;       /* offset 0x260 */
 +      unsigned int resv13[103];
 +      unsigned int l4lsclkstctrl;     /* offset 0x400 */
 +      unsigned int resv14[7];
 +      unsigned int l4lsclkctrl;       /* offset 0x420 */
 +      unsigned int resv15;
 +      unsigned int dcan0clkctrl;      /* offset 0x428 */
 +      unsigned int resv16;
 +      unsigned int dcan1clkctrl;      /* offset 0x430 */
 +      unsigned int resv17[13];
 +      unsigned int elmclkctrl;        /* offset 0x468 */
 +
 +      unsigned int resv18[3];
 +      unsigned int gpio1clkctrl;      /* offset 0x478 */
 +      unsigned int resv19;
 +      unsigned int gpio2clkctrl;      /* offset 0x480 */
 +      unsigned int resv20;
 +      unsigned int gpio3clkctrl;      /* offset 0x488 */
 +      unsigned int resv41;
 +      unsigned int gpio4clkctrl;      /* offset 0x490 */
 +      unsigned int resv42;
 +      unsigned int gpio5clkctrl;      /* offset 0x498 */
 +      unsigned int resv21[3];
 +
 +      unsigned int i2c1clkctrl;       /* offset 0x4A8 */
 +      unsigned int resv22;
 +      unsigned int i2c2clkctrl;       /* offset 0x4B0 */
 +      unsigned int resv23[3];
 +      unsigned int mmc0clkctrl;       /* offset 0x4C0 */
 +      unsigned int resv24;
 +      unsigned int mmc1clkctrl;       /* offset 0x4C8 */
 +
 +      unsigned int resv25[13];
 +      unsigned int spi0clkctrl;       /* offset 0x500 */
 +      unsigned int resv26;
 +      unsigned int spi1clkctrl;       /* offset 0x508 */
 +      unsigned int resv27[9];
 +      unsigned int timer2clkctrl;     /* offset 0x530 */
 +      unsigned int resv28;
 +      unsigned int timer3clkctrl;     /* offset 0x538 */
 +      unsigned int resv29;
 +      unsigned int timer4clkctrl;     /* offset 0x540 */
 +      unsigned int resv30[5];
 +      unsigned int timer7clkctrl;     /* offset 0x558 */
 +
 +      unsigned int resv31[9];
 +      unsigned int uart1clkctrl;      /* offset 0x580 */
 +      unsigned int resv32;
 +      unsigned int uart2clkctrl;      /* offset 0x588 */
 +      unsigned int resv33;
 +      unsigned int uart3clkctrl;      /* offset 0x590 */
 +      unsigned int resv34;
 +      unsigned int uart4clkctrl;      /* offset 0x598 */
 +      unsigned int resv35;
 +      unsigned int uart5clkctrl;      /* offset 0x5A0 */
 +      unsigned int resv36[87];
 +
 +      unsigned int emifclkstctrl;     /* offset 0x700 */
 +      unsigned int resv361[7];
 +      unsigned int emifclkctrl;       /* offset 0x720 */
 +      unsigned int resv37[3];
 +      unsigned int emiffwclkctrl;     /* offset 0x730 */
 +      unsigned int resv371;
 +      unsigned int otfaemifclkctrl;   /* offset 0x738 */
 +      unsigned int resv38[57];
 +      unsigned int lcdclkctrl;        /* offset 0x820 */
 +      unsigned int resv39[183];
 +      unsigned int cpswclkstctrl;     /* offset 0xB00 */
 +      unsigned int resv40[7];
 +      unsigned int cpgmac0clkctrl;    /* offset 0xB20 */
 +};
 +
 +struct cm_device_inst {
 +      unsigned int cm_clkout1_ctrl;
 +      unsigned int cm_dll_ctrl;
 +};
 +
 +struct cm_dpll {
 +      unsigned int resv1;
 +      unsigned int clktimer2clk;      /* offset 0x04 */
 +};
 +#endif /* CONFIG_AM43XX */
 +
  /* Control Module RTC registers */
  struct cm_rtc {
        unsigned int rtcclkctrl;        /* offset 0x0 */
@@@ -443,10 -273,19 +445,10 @@@ struct gptimer 
        unsigned int twpc;              /* offset 0x48 */
        unsigned int tmar;              /* offset 0x4c */
        unsigned int tcar1;             /* offset 0x50 */
-       unsigned int tscir;             /* offset 0x54 */
+       unsigned int tsicr;             /* offset 0x54 */
        unsigned int tcar2;             /* offset 0x58 */
  };
  
 -/* RTC Registers */
 -struct rtc_regs {
 -      unsigned int res[21];
 -      unsigned int osc;               /* offset 0x54 */
 -      unsigned int res2[5];
 -      unsigned int kick0r;            /* offset 0x6c */
 -      unsigned int kick1r;            /* offset 0x70 */
 -};
 -
  /* UART Registers */
  struct uart_sys {
        unsigned int resv1[21];
@@@ -464,9 -303,7 +466,9 @@@ struct ctrl_stat 
        unsigned int resv1[16];
        unsigned int statusreg;         /* ofset 0x40 */
        unsigned int resv2[51];
-       unsigned int secure_emif_sdram_config;  /* offset 0x0110 */
+       unsigned int emif_sdram_config; /* offset 0x0110 */
 +      unsigned int resv3[319];
 +      unsigned int dev_attr;
  };
  
  /* AM33XX GPIO registers */
  #define OMAP_GPIO_SETDATAOUT          0x0194
  
  /* Control Device Register */
 +
 + /* Control Device Register */
 +#define MREQPRIO_0_SAB_INIT1_MASK     0xFFFFFF8F
 +#define MREQPRIO_0_SAB_INIT0_MASK     0xFFFFFFF8
 +#define MREQPRIO_1_DSS_MASK           0xFFFFFF8F
 +
  struct ctrl_dev {
        unsigned int deviceid;          /* offset 0x00 */
        unsigned int resv1[7];
        unsigned int macid1h;           /* offset 0x3c */
        unsigned int resv4[4];
        unsigned int miisel;            /* offset 0x50 */
 +      unsigned int resv5[7];
 +      unsigned int mreqprio_0;        /* offset 0x70 */
 +      unsigned int mreqprio_1;        /* offset 0x74 */
 +      unsigned int resv6[97];
 +      unsigned int efuse_sma;         /* offset 0x1FC */
 +};
 +
 +/* Bandwidth Limiter Portion of the L3Fast Configuration Register */
 +#define BW_LIMITER_BW_FRAC_MASK         0xFFFFFFE0
 +#define BW_LIMITER_BW_INT_MASK          0xFFFFFFF0
 +#define BW_LIMITER_BW_WATERMARK_MASK    0xFFFFF800
 +
 +struct l3f_cfg_bwlimiter {
 +      u32 padding0[2];
 +      u32 modena_init0_bw_fractional;
 +      u32 modena_init0_bw_integer;
 +      u32 modena_init0_watermark_0;
 +};
 +
 +/* gmii_sel register defines */
 +#define GMII1_SEL_MII         0x0
 +#define GMII1_SEL_RMII                0x1
 +#define GMII1_SEL_RGMII               0x2
 +#define GMII2_SEL_MII         0x0
 +#define GMII2_SEL_RMII                0x4
 +#define GMII2_SEL_RGMII               0x8
 +#define RGMII1_IDMODE         BIT(4)
 +#define RGMII2_IDMODE         BIT(5)
 +#define RMII1_IO_CLK_EN               BIT(6)
 +#define RMII2_IO_CLK_EN               BIT(7)
 +
 +#define MII_MODE_ENABLE               (GMII1_SEL_MII | GMII2_SEL_MII)
 +#define RMII_MODE_ENABLE        (GMII1_SEL_RMII | GMII2_SEL_RMII)
 +#define RGMII_MODE_ENABLE     (GMII1_SEL_RGMII | GMII2_SEL_RGMII)
 +#define RGMII_INT_DELAY               (RGMII1_IDMODE | RGMII2_IDMODE)
 +#define RMII_CHIPCKL_ENABLE     (RMII1_IO_CLK_EN | RMII2_IO_CLK_EN)
 +
 +/* PWMSS */
 +struct pwmss_regs {
 +      unsigned int idver;
 +      unsigned int sysconfig;
 +      unsigned int clkconfig;
 +      unsigned int clkstatus;
 +};
 +#define ECAP_CLK_EN           BIT(0)
 +#define ECAP_CLK_STOP_REQ     BIT(1)
 +
 +struct pwmss_ecap_regs {
 +      unsigned int tsctr;
 +      unsigned int ctrphs;
 +      unsigned int cap1;
 +      unsigned int cap2;
 +      unsigned int cap3;
 +      unsigned int cap4;
 +      unsigned int resv1[4];
 +      unsigned short ecctl1;
 +      unsigned short ecctl2;
  };
  
 -void init_timer(void);
 +/* Capture Control register 2 */
 +#define ECTRL2_SYNCOSEL_MASK  (0x03 << 6)
 +#define ECTRL2_MDSL_ECAP      BIT(9)
 +#define ECTRL2_CTRSTP_FREERUN BIT(4)
 +#define ECTRL2_PLSL_LOW               BIT(10)
 +#define ECTRL2_SYNC_EN                BIT(5)
  
 -unsigned long lcdc_clk_rate(void);
+ #define clk_get_rate(c,p)                                     \
+       __clk_get_rate(readl(&(c)->clkseldpll##p),              \
+               readl(&(c)->divm2dpll##p))
+ unsigned long __clk_get_rate(u32 m_n, u32 div_m2);
+ unsigned long mpu_clk_rate(void);
  #endif /* __ASSEMBLY__ */
  #endif /* __KERNEL_STRICT_NAMES */
  
+ /* Ethernet MAC ID from EFuse */
+ #define MAC_ID0_LO    (CTRL_BASE + 0x630)
+ #define MAC_ID0_HI    (CTRL_BASE + 0x634)
+ #define MAC_ID1_LO    (CTRL_BASE + 0x638)
+ #define MAC_ID1_HI    (CTRL_BASE + 0x63c)
+ #define MAC_MII_SEL   (CTRL_BASE + 0x650)
  #endif /* _AM33XX_CPU_H */
index 97bbfe2e65e887991899889df3fb23e55052a43e,d8e9ee62aaa862163221554565f2710499c9e470..719f3e22905c2bdf86b2f3e77f97c8ef43d80934
  /* AM335X EMIF Register values */
  #define VTP_CTRL_READY                (0x1 << 5)
  #define VTP_CTRL_ENABLE               (0x1 << 6)
- #define VTP_CTRL_START_EN     (0x1)
+ #define VTP_CTRL_FILTER_SHIFT 1
+ #define VTP_CTRL_FILTER_MASK  (0x7 << VTP_CTRL_FILTER_SHIFT)
+ #define VTP_CTRL_FILTER(n)    (((n) << VTP_CTRL_FILTER_SHIFT) & VTP_CTRL_FILTER_MASK)
+ #define VTP_CTRL_START_EN     (0x1 << 0)
+ #define PHY_DLL_LOCK_DIFF     0x0
 +#ifdef CONFIG_AM43XX
 +#define DDR_CKE_CTRL_NORMAL   0x3
 +#else
  #define DDR_CKE_CTRL_NORMAL   0x1
 +#endif
  #define PHY_EN_DYN_PWRDN      (0x1 << 20)
  
  /* Micron MT47H128M16RT-25E */
  #define MT47H128M16RT25E_EMIF_TIM3            0x0000033F
  #define MT47H128M16RT25E_EMIF_SDCFG           0x41805332
  #define MT47H128M16RT25E_EMIF_SDREF           0x0000081a
 -#define MT47H128M16RT25E_DLL_LOCK_DIFF                0x0
  #define MT47H128M16RT25E_RATIO                        0x80
 -#define MT47H128M16RT25E_INVERT_CLKOUT                0x00
  #define MT47H128M16RT25E_RD_DQS                       0x12
 -#define MT47H128M16RT25E_WR_DQS                       0x00
 -#define MT47H128M16RT25E_PHY_WRLVL            0x00
 -#define MT47H128M16RT25E_PHY_GATELVL          0x00
  #define MT47H128M16RT25E_PHY_WR_DATA          0x40
  #define MT47H128M16RT25E_PHY_FIFO_WE          0x80
 -#define MT47H128M16RT25E_PHY_RANK0_DELAY              0x1
  #define MT47H128M16RT25E_IOCTRL_VALUE         0x18B
  
  /* Micron MT41J128M16JT-125 */
 -#define MT41J128MJT125_EMIF_READ_LATENCY      0x06
 +#define MT41J128MJT125_EMIF_READ_LATENCY      0x100006
  #define MT41J128MJT125_EMIF_TIM1              0x0888A39B
  #define MT41J128MJT125_EMIF_TIM2              0x26337FDA
  #define MT41J128MJT125_EMIF_TIM3              0x501F830F
  #define MT41J128MJT125_EMIF_SDCFG             0x61C04AB2
  #define MT41J128MJT125_EMIF_SDREF             0x0000093B
  #define MT41J128MJT125_ZQ_CFG                 0x50074BE4
 -#define MT41J128MJT125_DLL_LOCK_DIFF          0x1
  #define MT41J128MJT125_RATIO                  0x40
  #define MT41J128MJT125_INVERT_CLKOUT          0x1
  #define MT41J128MJT125_RD_DQS                 0x3B
  #define MT41J128MJT125_PHY_FIFO_WE            0x100
  #define MT41J128MJT125_IOCTRL_VALUE           0x18B
  
 +/* Micron MT41K128M16JT-187E */
 +#define MT41K128MJT187E_EMIF_READ_LATENCY     0x06
 +#define MT41K128MJT187E_EMIF_TIM1             0x0888B3DB
 +#define MT41K128MJT187E_EMIF_TIM2             0x36337FDA
 +#define MT41K128MJT187E_EMIF_TIM3             0x501F830F
 +#define MT41K128MJT187E_EMIF_SDCFG            0x61C04AB2
 +#define MT41K128MJT187E_EMIF_SDREF            0x0000093B
 +#define MT41K128MJT187E_ZQ_CFG                        0x50074BE4
 +#define MT41K128MJT187E_RATIO                 0x40
 +#define MT41K128MJT187E_INVERT_CLKOUT         0x1
 +#define MT41K128MJT187E_RD_DQS                        0x3B
 +#define MT41K128MJT187E_WR_DQS                        0x85
 +#define MT41K128MJT187E_PHY_WR_DATA           0xC1
 +#define MT41K128MJT187E_PHY_FIFO_WE           0x100
 +#define MT41K128MJT187E_IOCTRL_VALUE          0x18B
 +
 +/* Micron MT41J64M16JT-125 */
 +#define MT41J64MJT125_EMIF_SDCFG              0x61C04A32
 +
 +/* Micron MT41J256M16JT-125 */
 +#define MT41J256MJT125_EMIF_SDCFG             0x61C04B32
 +
  /* Micron MT41J256M8HX-15E */
 -#define MT41J256M8HX15E_EMIF_READ_LATENCY     0x06
 +#define MT41J256M8HX15E_EMIF_READ_LATENCY     0x100006
  #define MT41J256M8HX15E_EMIF_TIM1             0x0888A39B
  #define MT41J256M8HX15E_EMIF_TIM2             0x26337FDA
  #define MT41J256M8HX15E_EMIF_TIM3             0x501F830F
  #define MT41J256M8HX15E_EMIF_SDCFG            0x61C04B32
  #define MT41J256M8HX15E_EMIF_SDREF            0x0000093B
  #define MT41J256M8HX15E_ZQ_CFG                        0x50074BE4
 -#define MT41J256M8HX15E_DLL_LOCK_DIFF         0x1
  #define MT41J256M8HX15E_RATIO                 0x40
  #define MT41J256M8HX15E_INVERT_CLKOUT         0x1
  #define MT41J256M8HX15E_RD_DQS                        0x3B
  #define MT41K256M16HA125E_EMIF_SDCFG          0x61C05332
  #define MT41K256M16HA125E_EMIF_SDREF          0xC30
  #define MT41K256M16HA125E_ZQ_CFG              0x50074BE4
 -#define MT41K256M16HA125E_DLL_LOCK_DIFF               0x1
  #define MT41K256M16HA125E_RATIO                       0x80
  #define MT41K256M16HA125E_INVERT_CLKOUT               0x0
  #define MT41K256M16HA125E_RD_DQS              0x38
  #define MT41K256M16HA125E_IOCTRL_VALUE                0x18B
  
  /* Micron MT41J512M8RH-125 on EVM v1.5 */
 -#define MT41J512M8RH125_EMIF_READ_LATENCY     0x06
 +#define MT41J512M8RH125_EMIF_READ_LATENCY     0x100006
  #define MT41J512M8RH125_EMIF_TIM1             0x0888A39B
  #define MT41J512M8RH125_EMIF_TIM2             0x26517FDA
  #define MT41J512M8RH125_EMIF_TIM3             0x501F84EF
  #define MT41J512M8RH125_EMIF_SDCFG            0x61C04BB2
  #define MT41J512M8RH125_EMIF_SDREF            0x0000093B
  #define MT41J512M8RH125_ZQ_CFG                        0x50074BE4
 -#define MT41J512M8RH125_DLL_LOCK_DIFF         0x1
  #define MT41J512M8RH125_RATIO                 0x80
  #define MT41J512M8RH125_INVERT_CLKOUT         0x0
  #define MT41J512M8RH125_RD_DQS                        0x3B
  #define MT41J512M8RH125_IOCTRL_VALUE          0x18B
  
  /* Samsung K4B2G1646E-BIH9 */
 -#define K4B2G1646EBIH9_EMIF_READ_LATENCY      0x06
 -#define K4B2G1646EBIH9_EMIF_TIM1              0x0888A39B
 -#define K4B2G1646EBIH9_EMIF_TIM2              0x2A04011A
 -#define K4B2G1646EBIH9_EMIF_TIM3              0x501F820F
 -#define K4B2G1646EBIH9_EMIF_SDCFG             0x61C24AB2
 -#define K4B2G1646EBIH9_EMIF_SDREF             0x0000093B
 +#define K4B2G1646EBIH9_EMIF_READ_LATENCY      0x100007
 +#define K4B2G1646EBIH9_EMIF_TIM1              0x0AAAE51B
 +#define K4B2G1646EBIH9_EMIF_TIM2              0x2A1D7FDA
 +#define K4B2G1646EBIH9_EMIF_TIM3              0x501F83FF
 +#define K4B2G1646EBIH9_EMIF_SDCFG             0x61C052B2
 +#define K4B2G1646EBIH9_EMIF_SDREF             0x00000C30
  #define K4B2G1646EBIH9_ZQ_CFG                 0x50074BE4
 -#define K4B2G1646EBIH9_DLL_LOCK_DIFF          0x1
 -#define K4B2G1646EBIH9_RATIO                  0x40
 -#define K4B2G1646EBIH9_INVERT_CLKOUT          0x1
 -#define K4B2G1646EBIH9_RD_DQS                 0x3B
 -#define K4B2G1646EBIH9_WR_DQS                 0x85
 -#define K4B2G1646EBIH9_PHY_FIFO_WE            0x100
 -#define K4B2G1646EBIH9_PHY_WR_DATA            0xC1
 +#define K4B2G1646EBIH9_RATIO                  0x80
 +#define K4B2G1646EBIH9_INVERT_CLKOUT          0x0
 +#define K4B2G1646EBIH9_RD_DQS                 0x35
 +#define K4B2G1646EBIH9_WR_DQS                 0x3A
 +#define K4B2G1646EBIH9_PHY_FIFO_WE            0x97
 +#define K4B2G1646EBIH9_PHY_WR_DATA            0x76
  #define K4B2G1646EBIH9_IOCTRL_VALUE           0x18B
  
 +#define  LPDDR2_ADDRCTRL_IOCTRL_VALUE   0x294
 +#define  LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE 0x00000000
 +#define  LPDDR2_ADDRCTRL_WD1_IOCTRL_VALUE 0x00000000
 +#define  LPDDR2_DATA0_IOCTRL_VALUE   0x20000294
 +#define  LPDDR2_DATA1_IOCTRL_VALUE   0x20000294
 +#define  LPDDR2_DATA2_IOCTRL_VALUE   0x20000294
 +#define  LPDDR2_DATA3_IOCTRL_VALUE   0x20000294
 +
 +#define  DDR3_ADDRCTRL_WD0_IOCTRL_VALUE 0x00000000
 +#define  DDR3_ADDRCTRL_WD1_IOCTRL_VALUE 0x00000000
 +#define  DDR3_ADDRCTRL_IOCTRL_VALUE   0x84
 +#define  DDR3_DATA0_IOCTRL_VALUE   0x84
 +#define  DDR3_DATA1_IOCTRL_VALUE   0x84
 +#define  DDR3_DATA2_IOCTRL_VALUE   0x84
 +#define  DDR3_DATA3_IOCTRL_VALUE   0x84
 +
  /**
   * Configure DMM
   */
@@@ -165,7 -138,6 +169,7 @@@ void config_dmm(const struct dmm_lisa_m
   * Configure SDRAM
   */
  void config_sdram(const struct emif_regs *regs, int nr);
 +void config_sdram_emif4d5(const struct emif_regs *regs, int nr);
  
  /**
   * Set SDRAM timings
@@@ -180,15 -152,18 +184,15 @@@ void config_ddr_phy(const struct emif_r
  struct ddr_cmd_regs {
        unsigned int resv0[7];
        unsigned int cm0csratio;        /* offset 0x01C */
 -      unsigned int resv1[2];
 -      unsigned int cm0dldiff;         /* offset 0x028 */
 +      unsigned int resv1[3];
        unsigned int cm0iclkout;        /* offset 0x02C */
        unsigned int resv2[8];
        unsigned int cm1csratio;        /* offset 0x050 */
 -      unsigned int resv3[2];
 -      unsigned int cm1dldiff;         /* offset 0x05C */
 +      unsigned int resv3[3];
        unsigned int cm1iclkout;        /* offset 0x060 */
        unsigned int resv4[8];
        unsigned int cm2csratio;        /* offset 0x084 */
 -      unsigned int resv5[2];
 -      unsigned int cm2dldiff;         /* offset 0x090 */
 +      unsigned int resv5[3];
        unsigned int cm2iclkout;        /* offset 0x094 */
        unsigned int resv6[3];
  };
@@@ -220,43 -195,37 +224,43 @@@ struct ddr_data_regs 
   * correspond to DATA1 registers defined here.
   */
  struct ddr_regs {
 -      unsigned int resv0[7];
 -      unsigned int cm0csratio;        /* offset 0x01C */
 +      unsigned int resv0[3];
 +      unsigned int cm0config;         /* offset 0x00C */
 +      unsigned int cm0configclk;      /* offset 0x010 */
        unsigned int resv1[2];
 -      unsigned int cm0dldiff;         /* offset 0x028 */
 +      unsigned int cm0csratio;        /* offset 0x01C */
 +      unsigned int resv2[3];
        unsigned int cm0iclkout;        /* offset 0x02C */
 -      unsigned int resv2[8];
 +      unsigned int resv3[4];
 +      unsigned int cm1config;         /* offset 0x040 */
 +      unsigned int cm1configclk;      /* offset 0x044 */
 +      unsigned int resv4[2];
        unsigned int cm1csratio;        /* offset 0x050 */
 -      unsigned int resv3[2];
 -      unsigned int cm1dldiff;         /* offset 0x05C */
 +      unsigned int resv5[3];
        unsigned int cm1iclkout;        /* offset 0x060 */
 -      unsigned int resv4[8];
 +      unsigned int resv6[4];
 +      unsigned int cm2config;         /* offset 0x074 */
 +      unsigned int cm2configclk;      /* offset 0x078 */
 +      unsigned int resv7[2];
        unsigned int cm2csratio;        /* offset 0x084 */
 -      unsigned int resv5[2];
 -      unsigned int cm2dldiff;         /* offset 0x090 */
 +      unsigned int resv8[3];
        unsigned int cm2iclkout;        /* offset 0x094 */
 -      unsigned int resv6[12];
 +      unsigned int resv9[12];
        unsigned int dt0rdsratio0;      /* offset 0x0C8 */
 -      unsigned int resv7[4];
 +      unsigned int resv10[4];
        unsigned int dt0wdsratio0;      /* offset 0x0DC */
 -      unsigned int resv8[4];
 +      unsigned int resv11[4];
        unsigned int dt0wiratio0;       /* offset 0x0F0 */
 -      unsigned int resv9;
 +      unsigned int resv12;
        unsigned int dt0wimode0;        /* offset 0x0F8 */
        unsigned int dt0giratio0;       /* offset 0x0FC */
 -      unsigned int resv10;
 +      unsigned int resv13;
        unsigned int dt0gimode0;        /* offset 0x104 */
        unsigned int dt0fwsratio0;      /* offset 0x108 */
 -      unsigned int resv11[4];
 +      unsigned int resv14[4];
        unsigned int dt0dqoffset;       /* offset 0x11C */
        unsigned int dt0wrsratio0;      /* offset 0x120 */
 -      unsigned int resv12[4];
 +      unsigned int resv15[4];
        unsigned int dt0rdelays0;       /* offset 0x134 */
        unsigned int dt0dldiff0;        /* offset 0x138 */
  };
@@@ -268,14 -237,17 +272,14 @@@ struct cmd_control 
        unsigned long cmd0csratio;
        unsigned long cmd0csforce;
        unsigned long cmd0csdelay;
 -      unsigned long cmd0dldiff;
        unsigned long cmd0iclkout;
        unsigned long cmd1csratio;
        unsigned long cmd1csforce;
        unsigned long cmd1csdelay;
 -      unsigned long cmd1dldiff;
        unsigned long cmd1iclkout;
        unsigned long cmd2csratio;
        unsigned long cmd2csforce;
        unsigned long cmd2csdelay;
 -      unsigned long cmd2dldiff;
        unsigned long cmd2iclkout;
  };
  
@@@ -289,6 -261,8 +293,6 @@@ struct ddr_data 
        unsigned long datagiratio0;
        unsigned long datafwsratio0;
        unsigned long datawrsratio0;
 -      unsigned long datauserank0delay;
 -      unsigned long datadldiff0;
  };
  
  /**
@@@ -311,27 -285,12 +315,27 @@@ struct ddr_cmdtctrl 
        unsigned int resv2[12];
        unsigned int dt0ioctl;
        unsigned int dt1ioctl;
 +      unsigned int dt2ioctrl;
 +      unsigned int dt3ioctrl;
 +      unsigned int resv3[4];
 +      unsigned int emif_sdram_config_ext;
 +};
 +
 +struct ctrl_ioregs {
 +      unsigned int cm0ioctl;
 +      unsigned int cm1ioctl;
 +      unsigned int cm2ioctl;
 +      unsigned int dt0ioctl;
 +      unsigned int dt1ioctl;
 +      unsigned int dt2ioctrl;
 +      unsigned int dt3ioctrl;
 +      unsigned int emif_sdram_config_ext;
  };
  
  /**
   * Configure DDR io control registers
   */
 -void config_io_ctrl(unsigned long val);
 +void config_io_ctrl(const struct ctrl_ioregs *ioregs);
  
  struct ddr_ctrl {
        unsigned int ddrioctrl;
        unsigned int ddrckectrl;
  };
  
 -void config_ddr(unsigned int pll, unsigned int ioctrl,
 +void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs,
                const struct ddr_data *data, const struct cmd_control *ctrl,
                const struct emif_regs *regs, int nr);
 +void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size);
  
  #endif  /* _DDR_DEFS_H */
index 220603db5a3858a7764e2233a5a0ef990be52eef,00af7995163046cac559cec5ec2587991bf28ff2..3f6365e9e8f1bb8dfc2ad681c283a2f20b66b298
  #define AM33XX_GPIO1_BASE       0x4804C000
  #define AM33XX_GPIO2_BASE       0x481AC000
  #define AM33XX_GPIO3_BASE       0x481AE000
 +#define AM33XX_GPIO4_BASE     0x48320000
 +#define AM33XX_GPIO5_BASE     0x48322000
  
+ #define AM33XX_GPIO_NR(bank, pin)     (((bank) << 5) | (pin))
 +/* GPIO CTRL register */
 +#define GPIO_CTRL_DISABLEMODULE_SHIFT 0
 +#define GPIO_CTRL_DISABLEMODULE_MASK  (1 << 0)
 +#define GPIO_CTRL_ENABLEMODULE                GPIO_CTRL_DISABLEMODULE_MASK
 +
 +/* GPIO OUTPUT ENABLE register */
 +#define GPIO_OE_ENABLE(x)             (1 << x)
 +
 +/* GPIO SETDATAOUT register */
 +#define GPIO_SETDATAOUT(x)            (1 << x)
  #endif /* _GPIO_AM33xx_H */
index 724e252946d4daa7b23f5ac0e140797c011f9d09,ae6e5339cf7068c0f7e0e683e453711fa841a0da..4274eba6d28c659c5ec8a20c62c971e4a41b4220
   */
  #define OMAP_HSMMC1_BASE              0x48060100
  #define OMAP_HSMMC2_BASE              0x481D8100
+ #define OMAP_HSMMC3_BASE              0x47810100
  
  #if defined(CONFIG_TI814X)
  #undef MMC_CLOCK_REFERENCE
  #define MMC_CLOCK_REFERENCE   192 /* MHz */
 +#elif defined(CONFIG_TI816X)
 +#undef MMC_CLOCK_REFERENCE
 +#define MMC_CLOCK_REFERENCE   48 /* MHz */
  #endif
  
  #endif /* MMC_HOST_DEF_H */
index 4968d3dd2e6cd732f4f49482a78464bea8c0d50f,d13af944953cc3de68012499d7aa00d42a828dfb..518cc8182b4f889868f1ca673c4ae12ad60f6855
@@@ -10,7 -10,7 +10,7 @@@
  
  #ifndef __ASSEMBLY__
  struct exynos4_sysreg {
-       unsigned char   res1[0x210];
+       unsigned int    res1[0x210 / 4];
        unsigned int    display_ctrl;
        unsigned int    display_ctrl2;
        unsigned int    camera_control;
@@@ -19,7 -19,7 +19,7 @@@
  };
  
  struct exynos5_sysreg {
-       unsigned char   res1[0x214];
+       unsigned int    res1[0x214 / 4];
        unsigned int    disp1blk_cfg;
        unsigned int    disp2blk_cfg;
        unsigned int    hdcp_e_fuse;
@@@ -28,7 -28,7 +28,7 @@@
        unsigned int    reserved;
        unsigned int    ispblk_cfg;
        unsigned int    usb20phy_cfg;
-       unsigned char   res2[0x29c];
+       unsigned int    res2[0x29c / 4];
        unsigned int    mipi_dphy;
        unsigned int    dptx_dphy;
        unsigned int    phyclk_sel;
@@@ -39,6 -39,5 +39,6 @@@
  
  void set_usbhost_mode(unsigned int mode);
  void set_system_display_ctrl(void);
 +int exynos_lcd_early_init(const void *blob);
  
  #endif        /* _EXYNOS4_SYSTEM_H */
index 3db4112d1f4abfae6ec4cbdb53a6bfc01a310d42,47f4c0e2767f3e4882931fb6ecfa2e46779e46b5..f4582ee833a82b4884eaba639f171e8a7975bd6c
@@@ -39,20 -39,85 +39,86 @@@ enum mxc_clock 
        MXC_NFC_CLK,
        MXC_PERIPH_CLK,
        MXC_I2C_CLK,
+       MXC_AXI_A_CLK,
+       MXC_AXI_B_CLK,
+       MXC_EMI_SLOW_CLK,
+ };
+ struct clk {
+       const char *name;
+       int id;
+       /* Source clock this clk depends on */
+       struct clk *parent;
+       /* Secondary clock to enable/disable with this clock */
+       struct clk *secondary;
+       /* Current clock rate */
+       unsigned long rate;
+       /* Reference count of clock enable/disable */
+       __s8 usecount;
+       /* Register bit position for clock's enable/disable control. */
+       u8 enable_shift;
+       /* Register address for clock's enable/disable control. */
+       void *enable_reg;
+       u32 flags;
+       /*
+        * Function ptr to recalculate the clock's rate based on parent
+        * clock's rate
+        */
+       void (*recalc) (struct clk *);
+       /*
+        * Function ptr to set the clock to a new rate. The rate must match a
+        * supported rate returned from round_rate. Leave blank if clock is not
+       * programmable
+        */
+       int (*set_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to round the requested clock rate to the nearest
+        * supported rate that is less than or equal to the requested rate.
+        */
+       unsigned long (*round_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to enable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       int (*enable) (struct clk *);
+       /*
+        * Function ptr to disable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       void (*disable) (struct clk *);
+       /* Function ptr to set the parent clock of the clock. */
+       int (*set_parent) (struct clk *, struct clk *);
  };
  
  u32 imx_get_uartclk(void);
  u32 imx_get_fecclk(void);
  unsigned int mxc_get_clock(enum mxc_clock clk);
- int mxc_set_clock(u32 ref, u32 freq, u32 clk_type);
+ int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk);
+ int adjust_core_voltage(u32 freq);
  void set_usb_phy_clk(void);
 -void enable_usb_phy1_clk(unsigned char enable);
 -void enable_usb_phy2_clk(unsigned char enable);
 +void enable_usb_phy1_clk(bool enable);
 +void enable_usb_phy2_clk(bool enable);
  void set_usboh3_clk(void);
 -void enable_usboh3_clk(unsigned char enable);
 +void enable_usboh3_clk(bool enable);
  void mxc_set_sata_internal_clock(void);
  int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
  void enable_nfc_clk(unsigned char enable);
 +void enable_efuse_prog_supply(bool enable);
+ void ipu_clk_enable(void);
+ void ipu_clk_disable(void);
+ void ipu_di_clk_enable(int di);
+ void ipu_di_clk_disable(int di);
+ #ifdef CONFIG_MX53
+ void ldb_clk_enable(int ldb);
+ void ldb_clk_disable(int ldb);
+ #else
+ static inline void ldb_clk_enable(int ldb)
+ {
+ }
+ static inline void ldb_clk_disable(int ldb)
+ {
+ }
+ #endif /* CONFIG_MX53 */
  
  #endif /* __ASM_ARCH_CLOCK_H */
index b61c7b970a6bff4b801a39d449da45c268d17345,824d851804100f9cc73efb1821965903f75a9f64..fee81e490089fda5d9770d5f5dbb798bf144a62c
@@@ -303,11 -303,8 +303,11 @@@ struct mxc_ccm_reg 
  #define MXC_CCM_CSCDR1_UART_CLK_PODF_RD(r)            ((r) & 0x7)
  
  /* Define the bits in register CCDR */
- #define MXC_CCM_CCDR_IPU_HS_MASK                      (0x1 << 17)
+ #define MXC_CCM_CCDR_IPU_HS_MASK                      (0x1 << 21)
  
 +/* Define the bits in register CGPR */
 +#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE           (1 << 4)
 +
  /* Define the bits in register CCGRx */
  #define MXC_CCM_CCGR_CG_MASK                          0x3
  #define MXC_CCM_CCGR_CG_OFF                           0x0
  #endif
  
  /* Define the bits in register CLPCR */
- #define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                 (0x1 << 18)
+ #define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                       (0x1 << 18)
  
  #define       MXC_DPLLC_CTL_HFSM                              (1 << 7)
  #define       MXC_DPLLC_CTL_DPDCK0_2_EN                       (1 << 12)
index f059d0f664b35b4f5630347cdffeb60c56194efb,d9a7018a00faeeb31140b2f819831889b5351eb5..091055f8f07fb723f9fbb07a3acc802bcd008059
  #if defined(CONFIG_MX51)
  #define IRAM_BASE_ADDR                0x1FFE0000      /* internal ram */
  #define IPU_SOC_BASE_ADDR     0x40000000
- #define IPU_SOC_OFFSET                0x1E000000
- #define SPBA0_BASE_ADDR         0x70000000
- #define AIPS1_BASE_ADDR         0x73F00000
- #define AIPS2_BASE_ADDR         0x83F00000
- #define CSD0_BASE_ADDR          0x90000000
- #define CSD1_BASE_ADDR          0xA0000000
- #define NFC_BASE_ADDR_AXI       0xCFFF0000
- #define CS1_BASE_ADDR           0xB8000000
+ #define SPBA0_BASE_ADDR               0x70000000
+ #define AIPS1_BASE_ADDR               0x73F00000
+ #define AIPS2_BASE_ADDR               0x83F00000
+ #define CSD0_BASE_ADDR                0x90000000
+ #define CSD1_BASE_ADDR                0xA0000000
+ #define NFC_BASE_ADDR_AXI     0xCFFF0000
+ #define CS1_BASE_ADDR         0xB8000000
  #elif defined(CONFIG_MX53)
- #define IPU_SOC_BASE_ADDR     0x18000000
- #define IPU_SOC_OFFSET                0x06000000
- #define SPBA0_BASE_ADDR         0x50000000
- #define AIPS1_BASE_ADDR         0x53F00000
- #define AIPS2_BASE_ADDR         0x63F00000
- #define CSD0_BASE_ADDR          0x70000000
- #define CSD1_BASE_ADDR          0xB0000000
- #define NFC_BASE_ADDR_AXI       0xF7FF0000
- #define IRAM_BASE_ADDR          0xF8000000
- #define CS1_BASE_ADDR           0xF4000000
+ #define IPU_SOC_BASE_ADDR     0x00000000
+ #define SPBA0_BASE_ADDR               0x50000000
+ #define AIPS1_BASE_ADDR               0x53F00000
+ #define AIPS2_BASE_ADDR               0x63F00000
+ #define CSD0_BASE_ADDR                0x70000000
+ #define CSD1_BASE_ADDR                0xB0000000
+ #define NFC_BASE_ADDR_AXI     0xF7FF0000
+ #define IRAM_BASE_ADDR                0xF8000000
+ #define CS1_BASE_ADDR         0xF4000000
  #define SATA_BASE_ADDR                0x10000000
  #else
  #error "CPU_TYPE not defined"
@@@ -44,7 -42,7 +42,7 @@@
  #define MMC_SDHC1_BASE_ADDR   (SPBA0_BASE_ADDR + 0x00004000)
  #define MMC_SDHC2_BASE_ADDR   (SPBA0_BASE_ADDR + 0x00008000)
  #define UART3_BASE            (SPBA0_BASE_ADDR + 0x0000C000)
- #define CSPI1_BASE_ADDR       (SPBA0_BASE_ADDR + 0x00010000)
+ #define CSPI1_BASE_ADDR               (SPBA0_BASE_ADDR + 0x00010000)
  #define SSI2_BASE_ADDR                (SPBA0_BASE_ADDR + 0x00014000)
  #define MMC_SDHC3_BASE_ADDR   (SPBA0_BASE_ADDR + 0x00020000)
  #define MMC_SDHC4_BASE_ADDR   (SPBA0_BASE_ADDR + 0x00024000)
  #define GPC_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000D8000)
  
  #if defined(CONFIG_MX53)
- #define GPIO5_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000DC000)
- #define GPIO6_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E0000)
- #define GPIO7_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E4000)
+ #define GPIO5_BASE_ADDR               (AIPS1_BASE_ADDR + 0x000DC000)
+ #define GPIO6_BASE_ADDR               (AIPS1_BASE_ADDR + 0x000E0000)
+ #define GPIO7_BASE_ADDR               (AIPS1_BASE_ADDR + 0x000E4000)
  #define I2C3_BASE_ADDR                (AIPS1_BASE_ADDR + 0x000EC000)
- #define UART4_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000F0000)
+ #define UART4_BASE_ADDR               (AIPS1_BASE_ADDR + 0x000F0000)
  #endif
  /*
   * AIPS 2
@@@ -98,7 -96,7 +96,7 @@@
  #define IIM_BASE_ADDR         (AIPS2_BASE_ADDR + 0x00098000)
  #define CSU_BASE_ADDR         (AIPS2_BASE_ADDR + 0x0009C000)
  #define ARM_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000A0000)
- #define OWIRE_BASE_ADDR       (AIPS2_BASE_ADDR + 0x000A4000)
+ #define OWIRE_BASE_ADDR               (AIPS2_BASE_ADDR + 0x000A4000)
  #define FIRI_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000A8000)
  #define CSPI2_BASE_ADDR               (AIPS2_BASE_ADDR + 0x000AC000)
  #define SDMA_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000B0000)
  #define SAHARA_BASE_ADDR      (AIPS2_BASE_ADDR + 0x000F8000)
  
  #if defined(CONFIG_MX53)
- #define UART5_BASE_ADDR         (AIPS2_BASE_ADDR + 0x00090000)
+ #define UART5_BASE_ADDR               (AIPS2_BASE_ADDR + 0x00090000)
  #endif
  
  /*
   */
  #define WBED          1
  
 -/*
 - * WEIM WCR
 - */
 -#define BCM           1
 -#define GBCD(x)               (((x) & 0x3) << 1)
 -#define INTEN         (1 << 4)
 -#define INTPOL                (1 << 5)
 -#define WDOG_EN               (1 << 8)
 -#define WDOG_LIMIT(x) (((x) & 0x3) << 9)
 -
 -#define CS0_128                                       0
 -#define CS0_64M_CS1_64M                               1
 -#define CS0_64M_CS1_32M_CS2_32M                       2
 -#define CS0_32M_CS1_32M_CS2_32M_CS3_32M               3
 -
  /*
   * CSPI register definitions
   */
  #define MXC_CSPICTRL_CHAN     18
  
  /* Bit position inside CON register to be associated with SS */
 -#define MXC_CSPICON_POL               4
 -#define MXC_CSPICON_PHA               0
 -#define MXC_CSPICON_SSPOL     12
 +#define MXC_CSPICON_PHA               0  /* SCLK phase control */
 +#define MXC_CSPICON_POL               4  /* SCLK polarity */
 +#define MXC_CSPICON_SSPOL     12 /* SS polarity */
 +#define MXC_CSPICON_CTL               20 /* inactive state of SCLK */
  #define MXC_SPI_BASE_ADDRESSES \
        CSPI1_BASE_ADDR, \
        CSPI2_BASE_ADDR, \
  /*
   * Number of GPIO pins per port
   */
- #define GPIO_NUM_PIN            32
+ #define GPIO_NUM_PIN  32
  
  #define IIM_SREV      0x24
  #define ROM_SI_REV    0x48
  #define DP_MFD_665    (96 - 1)
  #define DP_MFN_665    89
  
+ #define DP_OP_600       ((6 << 4) + ((1 - 1)  << 0))
+ #define DP_MFD_600      (4 - 1)
+ #define DP_MFN_600      1
  #define DP_OP_532     ((5 << 4) + ((1 - 1)  << 0))
  #define DP_MFD_532    (24 - 1)
  #define DP_MFN_532    13
  
- #define DP_OP_400     ((8 << 4) + ((2 - 1)  << 0))
- #define DP_MFD_400    (3 - 1)
- #define DP_MFN_400    1
+ #define DP_OP_533     ((5 << 4) + ((1 - 1)  << 0))
+ #define DP_MFD_533    (9 - 1)
+ #define DP_MFN_533    5
  
  #define DP_OP_455     ((9 << 4) + ((2 - 1)  << 0))
  #define DP_MFD_455    (48 - 1)
  #define DP_MFN_455    23
  
+ #define DP_OP_400     ((8 << 4) + ((2 - 1)  << 0))
+ #define DP_MFD_400    (3 - 1)
+ #define DP_MFN_400    1
+ #define DP_OP_333     ((6 << 4) + ((2 - 1)  << 0))
+ #define DP_MFD_333    (16 - 1)
+ #define DP_MFN_333    15
  #define DP_OP_216     ((6 << 4) + ((3 - 1)  << 0))
  #define DP_MFD_216    (4 - 1)
  #define DP_MFN_216    3
  
- #define CHIP_REV_1_0            0x10
- #define CHIP_REV_1_1            0x11
- #define CHIP_REV_2_0            0x20
- #define CHIP_REV_2_5          0x25
- #define CHIP_REV_3_0            0x30
+ #define CHIP_REV_1_0  0x10
+ #define CHIP_REV_1_1  0x11
+ #define CHIP_REV_2_0  0x20
+ #define CHIP_REV_2_5  0x25
+ #define CHIP_REV_3_0  0x30
  
- #define BOARD_REV_1_0           0x0
- #define BOARD_REV_2_0           0x1
+ #define BOARD_REV_1_0 0x0
+ #define BOARD_REV_2_0 0x1
  
  #define BOARD_VER_OFFSET      0x8
  
- #define IMX_IIM_BASE            (IIM_BASE_ADDR)
+ #define IMX_IIM_BASE  IIM_BASE_ADDR
  
  #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
  #include <asm/types.h>
@@@ -409,7 -433,8 +419,7 @@@ struct weim 
  
  #if defined(CONFIG_MX51)
  struct iomuxc {
 -      u32     gpr0;
 -      u32     gpr1;
 +      u32     gpr[2];
        u32     omux0;
        u32     omux1;
        u32     omux2;
  };
  #elif defined(CONFIG_MX53)
  struct iomuxc {
 -      u32     gpr0;
 -      u32     gpr1;
 -      u32     gpr2;
 +      u32     gpr[3];
        u32     omux0;
        u32     omux1;
        u32     omux2;
@@@ -470,7 -497,7 +480,7 @@@ struct cspi_regs 
  struct iim_regs {
        u32     stat;
        u32     statm;
-       u32     err;
+       u32     err;
        u32     emask;
        u32     fctl;
        u32     ua;
        u32     sdat;
        u32     prev;
        u32     srev;
-       u32     prg_p;
+       u32     preg_p;
        u32     scs0;
        u32     scs1;
        u32     scs2;
index ac7705b3b099dd28ad7639670ad3d78df668987d,b164ec4f4ee0e760bd5bfec5fc11664ec14a9429..4a6ba21bd634a5290e91dd8bd26dda011f559141
@@@ -8,13 -8,19 +8,14 @@@
  #ifndef _SYS_PROTO_H_
  #define _SYS_PROTO_H_
  
 -#define MXC_CPU_MX51          0x51
 -#define MXC_CPU_MX53          0x53
 -#define MXC_CPU_MX6SL         0x60
 -#define MXC_CPU_MX6DL         0x61
 -#define MXC_CPU_MX6SOLO               0x62
 -#define MXC_CPU_MX6Q          0x63
 +#include "../arch-imx/cpu.h"
  
  #define is_soc_rev(rev)       ((get_cpu_rev() & 0xFF) - rev)
  u32 get_cpu_rev(void);
  unsigned imx_ddr_size(void);
  void sdelay(unsigned long);
  void set_chipselect_size(int const);
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
  
  /*
   * Initializes on-chip ethernet controllers.
index a6de5ee4bc12623a769b96a8f9bc86dde7b9e47f,a50a40e0464cb87c08af555f645233649d80d299..1b6c140c20294f9928905e7c4947a41bd8b6f572
@@@ -42,31 -42,68 +42,86 @@@ enum mxc_clock 
        MXC_I2C_CLK,
  };
  
 +enum enet_freq {
 +      ENET_25MHZ,
 +      ENET_50MHZ,
 +      ENET_100MHZ,
 +      ENET_125MHZ,
 +};
  
+ struct clk {
+       const char *name;
+       int id;
+       /* Source clock this clk depends on */
+       struct clk *parent;
+       /* Secondary clock to enable/disable with this clock */
+       struct clk *secondary;
+       /* Current clock rate */
+       unsigned long rate;
+       /* Reference count of clock enable/disable */
+       __s8 usecount;
+       /* Register bit position for clock's enable/disable control. */
+       u8 enable_shift;
+       /* Register address for clock's enable/disable control. */
+       void *enable_reg;
+       u32 flags;
+       /*
+        * Function ptr to recalculate the clock's rate based on parent
+        * clock's rate
+        */
+       void (*recalc) (struct clk *);
+       /*
+        * Function ptr to set the clock to a new rate. The rate must match a
+        * supported rate returned from round_rate. Leave blank if clock is not
+       * programmable
+        */
+       int (*set_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to round the requested clock rate to the nearest
+        * supported rate that is less than or equal to the requested rate.
+        */
+       unsigned long (*round_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to enable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       int (*enable) (struct clk *);
+       /*
+        * Function ptr to disable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       void (*disable) (struct clk *);
+       /* Function ptr to set the parent clock of the clock. */
+       int (*set_parent) (struct clk *, struct clk *);
+ };
  u32 imx_get_uartclk(void);
  u32 imx_get_fecclk(void);
  unsigned int mxc_get_clock(enum mxc_clock clk);
+ int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk);
 +void setup_gpmi_io_clk(u32 cfg);
 +void hab_caam_clock_enable(unsigned char enable);
  void enable_ocotp_clk(unsigned char enable);
  void enable_usboh3_clk(unsigned char enable);
 +void enable_uart_clk(unsigned char enable);
 +int enable_cspi_clock(unsigned char enable, unsigned spi_num);
 +int enable_usdhc_clk(unsigned char enable, unsigned bus_num);
  int enable_sata_clock(void);
 +void disable_sata_clock(void);
 +int enable_pcie_clock(void);
  int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 -
 +int enable_spi_clk(unsigned char enable, unsigned spi_num);
 +void enable_ipu_clock(void);
 +int enable_fec_anatop_clock(enum enet_freq freq);
 +void enable_enet_clk(unsigned char enable);
 +void enable_qspi_clk(int qspi_num);
 +void enable_thermal_clk(void);
+ void ipu_clk_enable(void);
+ void ipu_clk_disable(void);
+ void ipu_di_clk_enable(int di);
+ void ipu_di_clk_disable(int di);
+ void ldb_clk_enable(int ldb);
+ void ldb_clk_disable(int ldb);
+ void ocotp_clk_enable(void);
+ void ocotp_clk_disable(void);
  #endif /* __ASM_ARCH_CLOCK_H */
index 39f3c0707b8ee38eb9eda7e891a64e9f913298cc,e090f4baabfcbd46cb0c043ee725cbba94595df4..d882d3b008c9c782699aca531fe42b3dacaa068d
@@@ -55,69 -55,61 +55,21 @@@ struct mxc_ccm_reg 
        u32 CCGR6;      /* 0x0080 */
        u32 CCGR7;
        u32 cmeor;
-       u32 resv[0xfdd];
-       u32 analog_pll_sys;                     /* 0x4000 */
-       u32 analog_pll_sys_set;
-       u32 analog_pll_sys_clr;
-       u32 analog_pll_sys_tog;
-       u32 analog_usb1_pll_480_ctrl;           /* 0x4010 */
-       u32 analog_usb1_pll_480_ctrl_set;
-       u32 analog_usb1_pll_480_ctrl_clr;
-       u32 analog_usb1_pll_480_ctrl_tog;
-       u32 analog_reserved0[4];
-       u32 analog_pll_528;                     /* 0x4030 */
-       u32 analog_pll_528_set;
-       u32 analog_pll_528_clr;
-       u32 analog_pll_528_tog;
-       u32 analog_pll_528_ss;                  /* 0x4040 */
-       u32 analog_reserved1[3];
-       u32 analog_pll_528_num;                 /* 0x4050 */
-       u32 analog_reserved2[3];
-       u32 analog_pll_528_denom;               /* 0x4060 */
-       u32 analog_reserved3[3];
-       u32 analog_pll_audio;                   /* 0x4070 */
-       u32 analog_pll_audio_set;
-       u32 analog_pll_audio_clr;
-       u32 analog_pll_audio_tog;
-       u32 analog_pll_audio_num;               /* 0x4080*/
-       u32 analog_reserved4[3];
-       u32 analog_pll_audio_denom;             /* 0x4090 */
-       u32 analog_reserved5[3];
-       u32 analog_pll_video;                   /* 0x40a0 */
-       u32 analog_pll_video_set;
-       u32 analog_pll_video_clr;
-       u32 analog_pll_video_tog;
-       u32 analog_pll_video_num;               /* 0x40b0 */
-       u32 analog_reserved6[3];
-       u32 analog_pll_video_denom;             /* 0x40c0 */
-       u32 analog_reserved7[7];
-       u32 analog_pll_enet;                    /* 0x40e0 */
-       u32 analog_pll_enet_set;
-       u32 analog_pll_enet_clr;
-       u32 analog_pll_enet_tog;
-       u32 analog_pfd_480;                     /* 0x40f0 */
-       u32 analog_pfd_480_set;
-       u32 analog_pfd_480_clr;
-       u32 analog_pfd_480_tog;
-       u32 analog_pfd_528;                     /* 0x4100 */
-       u32 analog_pfd_528_set;
-       u32 analog_pfd_528_clr;
-       u32 analog_pfd_528_tog;
  };
 -
 -struct anatop_regs {
 -      mxs_reg_32(pll_arm);            /* 0x000 */
 -      mxs_reg_32(usb1_pll_480_ctrl);  /* 0x010 */
 -      mxs_reg_32(usb2_pll_480_ctrl);  /* 0x020 */
 -      mxs_reg_32(pll_528);            /* 0x030 */
 -      reg_32(pll_528_ss);             /* 0x040 */
 -      reg_32(pll_528_num);            /* 0x050 */
 -      reg_32(pll_528_denom);          /* 0x060 */
 -      mxs_reg_32(pll_audio);          /* 0x070 */
 -      reg_32(pll_audio_num);          /* 0x080 */
 -      reg_32(pll_audio_denom);        /* 0x090 */
 -      mxs_reg_32(pll_video);          /* 0x0a0 */
 -      reg_32(pll_video_num);          /* 0x0b0 */
 -      reg_32(pll_video_denom);        /* 0x0c0 */
 -      mxs_reg_32(pll_mlb);            /* 0x0d0 */
 -      mxs_reg_32(pll_enet);           /* 0x0e0 */
 -      mxs_reg_32(pfd_480);            /* 0x0f0 */
 -      mxs_reg_32(pfd_528);            /* 0x100 */
 -      mxs_reg_32(reg_1p1);            /* 0x110 */
 -      mxs_reg_32(reg_3p0);            /* 0x120 */
 -      mxs_reg_32(reg_2p5);            /* 0x130 */
 -      mxs_reg_32(reg_core);           /* 0x140 */
 -      mxs_reg_32(ana_misc0);          /* 0x150 */
 -      mxs_reg_32(ana_misc1);          /* 0x160 */
 -      mxs_reg_32(ana_misc2);          /* 0x170 */
 -      mxs_reg_32(tempsense0);         /* 0x180 */
 -      mxs_reg_32(tempsense1);         /* 0x190 */
 -      mxs_reg_32(usb1_vbus_detect);   /* 0x1a0 */
 -      mxs_reg_32(usb1_chrg_detect);   /* 0x1b0 */
 -      mxs_reg_32(usb1_vbus_det_stat); /* 0x1c0 */
 -      mxs_reg_32(usb1_chrg_det_stat); /* 0x1d0 */
 -      mxs_reg_32(usb1_loopback);      /* 0x1e0 */
 -      mxs_reg_32(usb1_misc);          /* 0x1f0 */
 -      mxs_reg_32(usb2_vbus_detect);   /* 0x200 */
 -      mxs_reg_32(usb2_chrg_detect);   /* 0x210 */
 -      mxs_reg_32(usb2_vbus_det_stat); /* 0x220 */
 -      mxs_reg_32(usb2_chrg_det_stat); /* 0x230 */
 -      mxs_reg_32(usb2_loopback);      /* 0x240 */
 -      mxs_reg_32(usb2_misc);          /* 0x250 */
 -      reg_32(digprog);                /* 0x260 */
 -      reg_32(rsrvd);                  /* 0x270 */
 -      reg_32(digprog_sololite);       /* 0x280 */
 -};
  #endif
  
  /* Define the bits in register CCR */
  #define MXC_CCM_CCR_RBC_EN                            (1 << 27)
- #define MXC_CCM_CCR_REG_BYPASS_CNT_MASK                       (0x3F << 21)
+ #define MXC_CCM_CCR_REG_BYPASS_CNT_MASK                       (0x3F << CCR_REG_BYPASS_CNT_OFFSET)
  #define MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET             21
- #define MXC_CCM_CCR_WB_COUNT_MASK                     0x7
+ #define MXC_CCM_CCR_WB_COUNT_MASK                     (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET)
  #define MXC_CCM_CCR_WB_COUNT_OFFSET                   (1 << 16)
  #define MXC_CCM_CCR_COSC_EN                           (1 << 12)
 -#define MXC_CCM_CCR_OSCNT_MASK                                (0xFF << MXC_CCM_CCR_OSCNT_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCR_OSCNT_MASK                                0x7F
 +#else
 +#define MXC_CCM_CCR_OSCNT_MASK                                0xFF
 +#endif
  #define MXC_CCM_CCR_OSCNT_OFFSET                      0
  
  /* Define the bits in register CCDR */
  
  /* Define the bits in register CACRR */
  #define MXC_CCM_CACRR_ARM_PODF_OFFSET                 0
- #define MXC_CCM_CACRR_ARM_PODF_MASK                   0x7
+ #define MXC_CCM_CACRR_ARM_PODF_MASK                   (0x7 << MXC_CCM_CACRR_ARM_PODF_OFFSET)
  
  /* Define the bits in register CBCDR */
- #define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK           (0x7 << 27)
+ #define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK           (0x7 << MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET)
  #define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET         27
  #define MXC_CCM_CBCDR_PERIPH2_CLK2_SEL                        (1 << 26)
  #define MXC_CCM_CBCDR_PERIPH_CLK_SEL                  (1 << 25)
- #define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK              (0x7 << 19)
 +#ifndef CONFIG_MX6SX
+ #define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK              (0x7 << MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET)
  #define MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET            19
- #define MXC_CCM_CBCDR_AXI_PODF_MASK                   (0x7 << 16)
 +#endif
+ #define MXC_CCM_CBCDR_AXI_PODF_MASK                   (0x7 << MXC_CCM_CBCDR_AXI_PODF_OFFSET)
  #define MXC_CCM_CBCDR_AXI_PODF_OFFSET                 16
- #define MXC_CCM_CBCDR_AHB_PODF_MASK                   (0x7 << 10)
+ #define MXC_CCM_CBCDR_AHB_PODF_MASK                   (0x7 << MXC_CCM_CBCDR_AHB_PODF_OFFSET)
  #define MXC_CCM_CBCDR_AHB_PODF_OFFSET                 10
- #define MXC_CCM_CBCDR_IPG_PODF_MASK                   (0x3 << 8)
+ #define MXC_CCM_CBCDR_IPG_PODF_MASK                   (0x3 << MXC_CCM_CBCDR_IPG_PODF_OFFSET)
  #define MXC_CCM_CBCDR_IPG_PODF_OFFSET                 8
  #define MXC_CCM_CBCDR_AXI_ALT_SEL                     (1 << 7)
  #define MXC_CCM_CBCDR_AXI_SEL                         (1 << 6)
- #define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK              (0x7 << 3)
+ #define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK              (0x7 << MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET)
  #define MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET            3
- #define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK          (0x7 << 0)
+ #define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK          (0x7 << MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET)
  #define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET                0
  
  /* Define the bits in register CBCMR */
- #define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK          (0x7 << 29)
+ #define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK          (0x7 << MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET)
  #define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET                29
- #define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK            (0x7 << 26)
+ #define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK            (0x7 << MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET)
  #define MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET          26
- #define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK            (0x7 << 23)
+ #define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK            (0x7 << MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET)
  #define MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET          23
- #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK                (0x3 << 21)
+ #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK                (0x3 << MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET      21
  #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK2_SEL            (1 << 20)
- #define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK         (0x3 << 18)
+ #define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK         (0x3 << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET               18
- #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK              (0x3 << 16)
 +#ifndef CONFIG_MX6SX
+ #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK              (0x3 << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET            16
- #define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK            (0x3 << 14)
+ #define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK            (0x3 << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET          14
- #define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK            (0x3 << 12)
 +#endif
+ #define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK            (0x3 << MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET)
  #define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET          12
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CBCMR_VDOAXI_CLK_SEL                  (1 << 11)
 +#endif
  #define MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL                        (1 << 10)
- #define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK               (0x3 << 8)
+ #define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK               (0x3 << MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET     8
- #define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK         (0x3 << 4)
+ #define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK         (0x3 << MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET)
  #define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET               4
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL                       (1 << 1)
  #define MXC_CCM_CBCMR_GPU2D_AXI_CLK_SEL                       (1 << 0)
 +#endif
  
  /* Define the bits in register CSCMR1 */
- #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK             (0x3 << 29)
+ #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK             (0x3 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET)
  #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET           29
- #define MXC_CCM_CSCMR1_QSPI1_PODF_MASK                        (0x7 << 26)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CSCMR1_ACLK_EMI_MASK                  (0x3 << 27)
++#define MXC_CCM_CSCMR1_QSPI1_PODF_MASK                        (0x7 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET)
 +#define MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET              26
 +#else
+ #define MXC_CCM_CSCMR1_ACLK_EMI_MASK                  (0x3 << MXC_CCM_CSCMR1_ACLK_EMI_OFFSET)
  #define MXC_CCM_CSCMR1_ACLK_EMI_OFFSET                        27
- #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK                (0x7 << 23)
 +#endif
+ #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK                (0x7 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET)
  #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET      23
- #define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK             (0x7 << 20)
 +/* ACLK_EMI_PODF is LCFIF2_PODF on MX6SX */
+ #define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK             (0x7 << MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET)
  #define MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET           20
  #define MXC_CCM_CSCMR1_USDHC4_CLK_SEL                 (1 << 19)
  #define MXC_CCM_CSCMR1_USDHC3_CLK_SEL                 (1 << 18)
  #define MXC_CCM_CSCMR1_USDHC2_CLK_SEL                 (1 << 17)
  #define MXC_CCM_CSCMR1_USDHC1_CLK_SEL                 (1 << 16)
- #define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK              (0x3 << 14)
+ #define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK              (0x3 << MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET            14
- #define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK              (0x3 << 12)
+ #define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK              (0x3 << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET            12
- #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK              (0x3 << 10)
+ #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK              (0x3 << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET            10
- #define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK             (0x7 << 7)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CSCMR1_PER_CLK_SEL_MASK                       (1 << 6)
++#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK             (0x7 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET)
 +#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET           7
 +#endif
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
- #define MXC_CCM_CSCMR1_PERCLK_PODF_MASK                       0x3F
++#define MXC_CCM_CSCMR1_PER_CLK_SEL_MASK                       (1 << MXC_CCM_CSCMR1_PER_CLK_SEL_OFFSET)
 +#define MXC_CCM_CSCMR1_PER_CLK_SEL_OFFSET             6
 +#endif
+ #define MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET             0
+ #define MXC_CCM_CSCMR1_PERCLK_PODF_MASK                       (0x3F << MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET)
  
  /* Define the bits in register CSCMR2 */
- #define MXC_CCM_CSCMR2_VID_CLK_SEL_MASK                       (0x7 << 21)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK              (0x3 << 19)
++#define MXC_CCM_CSCMR2_VID_CLK_SEL_MASK                       (0x7 << MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET)
 +#define MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET             21
 +#endif
+ #define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK              (0x3 << MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET)
  #define MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET            19
  #define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV                        (1 << 11)
  #define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV                        (1 << 10)
- #define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                       (0x3 << 8)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK              (0x3F << 2)
++#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                       (0x3 << MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET)
 +#define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET             8
- #define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                       (0x3F << 2)
++#define MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK              (0x3F << MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET)
 +#define MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET            2
 +#else
+ #define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                       (0x3F << MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET             2
 +#endif
  
  /* Define the bits in register CSCDR1 */
- #define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK              (0x7 << 25)
 +#ifndef CONFIG_MX6SX
+ #define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK              (0x7 << MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET)
  #define MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET            25
- #define MXC_CCM_CSCDR1_USDHC4_PODF_MASK                       (0x7 << 22)
 +#endif
+ #define MXC_CCM_CSCDR1_USDHC4_PODF_MASK                       (0x7 << MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET)
  #define MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET             22
- #define MXC_CCM_CSCDR1_USDHC3_PODF_MASK                       (0x7 << 19)
+ #define MXC_CCM_CSCDR1_USDHC3_PODF_MASK                       (0x7 << MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET)
  #define MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET             19
- #define MXC_CCM_CSCDR1_USDHC2_PODF_MASK                       (0x7 << 16)
+ #define MXC_CCM_CSCDR1_USDHC2_PODF_MASK                       (0x7 << MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET)
  #define MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET             16
- #define MXC_CCM_CSCDR1_USDHC1_PODF_MASK                       (0x7 << 11)
+ #define MXC_CCM_CSCDR1_USDHC1_PODF_MASK                       (0x7 << MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET)
  #define MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET             11
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET         8
- #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK           (0x7 << 8)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK           (0x7 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET)
  #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET         6
- #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK           (0x3 << 6)
+ #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK           (0x3 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET)
 +#endif
  #ifdef CONFIG_MX6SL
- #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK             0x1F
- #define MXC_CCM_CSCDR1_UART_CLK_SEL                   (1 << 6)
+ #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK             (0x1F << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET)
+ #define MXC_CCM_CSCDR1_UART_CLK_SEL                   (1 << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET)
  #else
- #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK             0x3F
+ #define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK             (0x3F << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CSCDR1_UART_CLK_SEL                   (1 << 6)
++#define MXC_CCM_CSCDR1_UART_CLK_SEL                   (1 << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET)
 +#endif
  #endif
+ #define MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET            6
  #define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET           0
  
  /* Define the bits in register CS1CDR */
- #define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK             (0x3F << 25)
+ #define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK             (0x3F << MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET)
  #define MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET           25
- #define MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK             (0x7 << 22)
++#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK             (0x7 << MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET)
 +#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET           22
- #define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK             (0x3F << 16)
+ #define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK             (0x3F << MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET)
  #define MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET           16
- #define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK             (0x3 << 9)
+ #define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK             (0x3 << MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET)
  #define MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET           9
- #define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK             (0x7 << 6)
+ #define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK             (0x7 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET)
  #define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET           6
- #define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK             0x3F
+ #define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK             (0x3F << MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET)
  #define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET           0
  
  /* Define the bits in register CS2CDR */
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK             (0x3F << 21)
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET           21
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PODF(v)                       (((v) & 0x3f) << 21)
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK             (0x7 << 18)
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET           18
- #define MXC_CCM_CS2CDR_QSPI2_CLK_PRED(v)                       (((v) & 0x7) << 18)
- #define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK              (0x7 << 15)
- #define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET            15
- #define MXC_CCM_CS2CDR_QSPI2_CLK_SEL(v)                        (((v) & 0x7) << 15)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK             (0x3F << 21)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK            (0x3F << MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET          21
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF(v)              (((v) & 0x3f) << MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK            (0x7 << MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET          18
++#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED(v)              (((v) & 0x7) << MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK             (0x7 << MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET)
++#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET           15
++#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL(v)                       (((v) & 0x7) << MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET)
 +#else
+ #define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK             (0x3F << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET)
  #define MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET           21
- #define MXC_CCM_CS2CDR_ENFC_CLK_PODF(v)                       (((v) & 0x3f) << 21)
- #define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK             (0x7 << 18)
+ #define MXC_CCM_CS2CDR_ENFC_CLK_PODF(v)                       (((v) & 0x3f) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET)
+ #define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK             (0x7 << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET)
  #define MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET           18
- #define MXC_CCM_CS2CDR_ENFC_CLK_PRED(v)                       (((v) & 0x7) << 18)
- #define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK              (0x3 << 16)
+ #define MXC_CCM_CS2CDR_ENFC_CLK_PRED(v)                       (((v) & 0x7) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET)
+ #define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK              (0x3 << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET)
  #define MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET            16
- #define MXC_CCM_CS2CDR_ENFC_CLK_SEL(v)                        (((v) & 0x3) << 16)
+ #define MXC_CCM_CS2CDR_ENFC_CLK_SEL(v)                        (((v) & 0x3) << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET)
 +#endif
- #define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK           (0x7 << 12)
+ #define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK           (0x7 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
  #define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET         12
- #define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK           (0x7 << 9)
+ #define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK           (0x7 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
  #define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET         9
- #define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK             (0x7 << 6)
+ #define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK             (0x7 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET)
  #define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET           6
- #define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK             0x3F
+ #define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK             (0x3F << MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET)
  #define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET           0
  
  /* Define the bits in register CDCDR */
- #define MXC_CCM_CDCDR_HSI_TX_PODF_MASK                        (0x7 << 29)
 +#ifndef CONFIG_MX6SX
+ #define MXC_CCM_CDCDR_HSI_TX_PODF_MASK                        (0x7 << MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET)
  #define MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET              29
--#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL                  (1 << 28)
++#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL_MASK             (1 << MXC_CCM_CDCDR_HSI_TX_CLK_SEL_OFFSET)
++#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL_OFFSET           28
 +#endif
- #define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK            (0x7 << 25)
+ #define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK            (0x7 << MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET)
  #define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET          25
- #define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK            (0x7 << 22)
+ #define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK            (0x7 << MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET)
 -#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET          19
 +#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET          22
- #define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK             (0x3 << 20)
+ #define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK             (0x3 << MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET)
  #define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET           20
- #define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK            (0x7 << 12)
+ #define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK            (0x7 << MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET)
  #define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET          12
- #define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK            (0x7 << 9)
+ #define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK            (0x7 << MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET)
  #define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET          9
- #define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK             (0x3 << 7)
+ #define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK             (0x3 << MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET)
  #define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET           7
  
  /* Define the bits in register CHSCCDR */
- #define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK         (0x7 << 15)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CHSCCDR_ENET_PODF_MASK                        (0x7 << 12)
++#define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK         (0x7 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET)
 +#define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET               15
- #define MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK             (0x7 << 9)
++#define MXC_CCM_CHSCCDR_ENET_PODF_MASK                        (0x7 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET)
 +#define MXC_CCM_CHSCCDR_ENET_PODF_OFFSET              12
- #define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_MASK           (0x7 << 6)
++#define MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK             (0x7 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET)
 +#define MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET           9
- #define MXC_CCM_CHSCCDR_M4_PODF_MASK                  (0x7 << 3)
++#define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_MASK           (0x7 << MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_OFFSET)
 +#define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_OFFSET         6
- #define MXC_CCM_CHSCCDR_M4_CLK_SEL_MASK                       (0x7)
++#define MXC_CCM_CHSCCDR_M4_PODF_MASK                  (0x7 << MXC_CCM_CHSCCDR_M4_PODF_OFFSET)
 +#define MXC_CCM_CHSCCDR_M4_PODF_OFFSET                        3
- #define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK     (0x7 << 15)
++#define MXC_CCM_CHSCCDR_M4_CLK_SEL_MASK                       (0x7 << MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET)
 +#define MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET             0
 +#else
+ #define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK     (0x7 << MXC_CCM_CHSCCDR_DI1_PRE_CLK_SEL_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET   15
- #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK            (0x7 << 12)
+ #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK            (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET          12
- #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK         (0x7 << 9)
+ #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK         (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET               9
- #define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK     (0x7 << 6)
+ #define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK     (0x7 << MXC_CCM_CHSCCDR_DI0_PRE_CLK_SEL_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET   6
- #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK            (0x7 << 3)
+ #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK            (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET          3
- #define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK         (0x7)
+ #define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK         (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
  #define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET               0
 +#endif
  
- #define CHSCCDR_CLK_SEL_LDB_DI0                               3
- #define CHSCCDR_PODF_DIVIDE_BY_3                      2
- #define CHSCCDR_IPU_PRE_CLK_540M_PFD                  5
  /* Define the bits in register CSCDR2 */
- #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK            (0x3F << 19)
+ #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK            (0x3F << MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET)
  #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET          19
- #define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_MASK     (0x7 << 15)
- #define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_OFFSET   15
- #define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_MASK            (0x7 << 12)
- #define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_OFFSET          12
- #define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_MASK         (0x7 << 9)
- #define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_OFFSET               9
 +/* All IPU2_DI1 are LCDIF1 on MX6SX */
- #define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_MASK     (0x7 << 6)
- #define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_OFFSET   6
- #define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_MASK            (0x7 << 3)
- #define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_OFFSET          3
- #define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_MASK         0x7
- #define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_OFFSET               0
+ #define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CSCDR2_DI1_PRE_CLK_SEL_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET    15
+ #define MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK             (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET           12
+ #define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK          (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET                9
 +/* All IPU2_DI0 are LCDIF2 on MX6SX */
+ #define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CSCDR2_DI0_PRE_CLK_SEL_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET    6
+ #define MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK             (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET           3
+ #define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK          (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET)
+ #define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET                0
  
  /* Define the bits in register CSCDR3 */
- #define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK             (0x7 << 16)
+ #define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK             (0x7 << MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET)
  #define MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET           16
- #define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK          (0x3 << 14)
+ #define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK          (0x3 << MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET                14
- #define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK             (0x7 << 11)
+ #define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK             (0x7 << MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET)
  #define MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET           11
- #define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK          (0x3 << 9)
+ #define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK          (0x3 << MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET)
  #define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET                9
  
  /* Define the bits in register CDHIPR */
  #define MXC_CCM_CDHIPR_ARM_PODF_BUSY                  (1 << 16)
  #define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY            (1 << 5)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CDHIPR_MMDC_CH0_PODF_BUSY             (1 << 4)
 +#endif
  #define MXC_CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY           (1 << 3)
  #define MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY             (1 << 2)
  #define MXC_CCM_CDHIPR_AHB_PODF_BUSY                  (1 << 1)
- #define MXC_CCM_CDHIPR_AXI_PODF_BUSY                  1
+ #define MXC_CCM_CDHIPR_AXI_PODF_BUSY                  (1 << 0)
  
  /* Define the bits in register CLPCR */
  #define MXC_CCM_CLPCR_MASK_L2CC_IDLE                  (1 << 27)
  #define MXC_CCM_CLPCR_MASK_SCU_IDLE                   (1 << 26)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CLPCR_MASK_CORE3_WFI                  (1 << 25)
  #define MXC_CCM_CLPCR_MASK_CORE2_WFI                  (1 << 24)
  #define MXC_CCM_CLPCR_MASK_CORE1_WFI                  (1 << 23)
 +#endif
  #define MXC_CCM_CLPCR_MASK_CORE0_WFI                  (1 << 22)
  #define MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS             (1 << 21)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS             (1 << 19)
  #define MXC_CCM_CLPCR_WB_CORE_AT_LPM                  (1 << 17)
 -#define MXC_CCM_CLPCR_WB_PER_AT_LPM                   (1 << 17)
 +#endif
 +#define MXC_CCM_CLPCR_WB_PER_AT_LPM                   (1 << 16)
  #define MXC_CCM_CLPCR_COSC_PWRDOWN                    (1 << 11)
- #define MXC_CCM_CLPCR_STBY_COUNT_MASK                 (0x3 << 9)
+ #define MXC_CCM_CLPCR_STBY_COUNT_MASK                 (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET)
  #define MXC_CCM_CLPCR_STBY_COUNT_OFFSET                       9
  #define MXC_CCM_CLPCR_VSTBY                           (1 << 8)
  #define MXC_CCM_CLPCR_DIS_REF_OSC                     (1 << 7)
  #define MXC_CCM_CLPCR_SBYOS                           (1 << 6)
  #define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM              (1 << 5)
- #define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK                       (0x3 << 3)
 +#ifndef CONFIG_MX6SX
+ #define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK                       (0x3 << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET)
  #define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET             3
  #define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY         (1 << 2)
- #define MXC_CCM_CLPCR_LPM_MASK                                0x3
 +#endif
+ #define MXC_CCM_CLPCR_LPM_MASK                                (0x3 << MXC_CCM_CLPCR_LPM_OFFSET)
  #define MXC_CCM_CLPCR_LPM_OFFSET                      0
  
  /* Define the bits in register CISR */
  #define MXC_CCM_CISR_ARM_PODF_LOADED                  (1 << 26)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CISR_MMDC_CH0_PODF_LOADED             (1 << 23)
 +#endif
  #define MXC_CCM_CISR_PERIPH_CLK_SEL_LOADED            (1 << 22)
  #define MXC_CCM_CISR_MMDC_CH1_PODF_LOADED             (1 << 21)
  #define MXC_CCM_CISR_AHB_PODF_LOADED                  (1 << 20)
  #define MXC_CCM_CISR_PERIPH2_CLK_SEL_LOADED           (1 << 19)
  #define MXC_CCM_CISR_AXI_PODF_LOADED                  (1 << 17)
  #define MXC_CCM_CISR_COSC_READY                               (1 << 6)
- #define MXC_CCM_CISR_LRF_PLL                          1
+ #define MXC_CCM_CISR_LRF_PLL                          (1 << 0)
  
  /* Define the bits in register CIMR */
  #define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED             (1 << 26)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CIMR_MASK_MMDC_CH0_PODF_LOADED                (1 << 23)
 +#endif
  #define MXC_CCM_CIMR_MASK_PERIPH_CLK_SEL_LOADED               (1 << 22)
  #define MXC_CCM_CIMR_MASK_MMDC_CH1_PODF_LOADED                (1 << 21)
  #define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED             (1 << 20)
 -#define MXC_CCM_CIMR_MASK_PERIPH2_CLK_SEL_LOADED      (1 << 22)
 +#define MXC_CCM_CIMR_MASK_PERIPH2_CLK_SEL_LOADED      (1 << 19)
  #define MXC_CCM_CIMR_MASK_AXI_PODF_LOADED             (1 << 17)
  #define MXC_CCM_CIMR_MASK_COSC_READY                  (1 << 6)
- #define MXC_CCM_CIMR_MASK_LRF_PLL                     1
+ #define MXC_CCM_CIMR_MASK_LRF_PLL                     (1 << 0)
  
  /* Define the bits in register CCOSR */
  #define MXC_CCM_CCOSR_CKO2_EN_OFFSET                  (1 << 24)
- #define MXC_CCM_CCOSR_CKO2_DIV_MASK                   (0x7 << 21)
+ #define MXC_CCM_CCOSR_CKO2_DIV_MASK                   (0x7 << MXC_CCM_CCOSR_CKO2_DIV_OFFSET)
  #define MXC_CCM_CCOSR_CKO2_DIV_OFFSET                 21
  #define MXC_CCM_CCOSR_CKO2_SEL_OFFSET                 16
- #define MXC_CCM_CCOSR_CKO2_SEL_MASK                   (0x1F << 16)
+ #define MXC_CCM_CCOSR_CKO2_SEL_MASK                   (0x1F << MXC_CCM_CCOSR_CKO2_SEL_OFFSET)
 +#define MXC_CCM_CCOSR_CLK_OUT_SEL                     (0x1 << 8)
  #define MXC_CCM_CCOSR_CKOL_EN                         (0x1 << 7)
- #define MXC_CCM_CCOSR_CKOL_DIV_MASK                   (0x7 << 4)
+ #define MXC_CCM_CCOSR_CKOL_DIV_MASK                   (0x7 << MXC_CCM_CCOSR_CKOL_DIV_OFFSET)
  #define MXC_CCM_CCOSR_CKOL_DIV_OFFSET                 4
- #define MXC_CCM_CCOSR_CKOL_SEL_MASK                   0xF
+ #define MXC_CCM_CCOSR_CKOL_SEL_MASK                   (0xF << MXC_CCM_CCOSR_CKOL_SEL_OFFSET)
  #define MXC_CCM_CCOSR_CKOL_SEL_OFFSET                 0
  
  /* Define the bits in registers CGPR */
 +#define MXC_CCM_CGPR_FAST_PLL_EN                      (1 << 16)
  #define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE           (1 << 4)
  #define MXC_CCM_CGPR_MMDC_EXT_CLK_DIS                 (1 << 2)
- #define MXC_CCM_CGPR_PMIC_DELAY_SCALER                        1
+ #define MXC_CCM_CGPR_PMIC_DELAY_SCALER                        (1 << 0)
  
  /* Define the bits in registers CCGRx */
  #define MXC_CCM_CCGR_CG_MASK                          3
  #define MXC_CCM_CCGR0_DCIC1_MASK                      (3 << MXC_CCM_CCGR0_DCIC1_OFFSET)
  #define MXC_CCM_CCGR0_DCIC2_OFFSET                    26
  #define MXC_CCM_CCGR0_DCIC2_MASK                      (3 << MXC_CCM_CCGR0_DCIC2_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR0_AIPS_TZ3_OFFSET                 30
 +#define MXC_CCM_CCGR0_AIPS_TZ3_MASK                   (3 << MXC_CCM_CCGR0_AIPS_TZ3_OFFSET)
 +#else
  #define MXC_CCM_CCGR0_DTCP_OFFSET                     28
  #define MXC_CCM_CCGR0_DTCP_MASK                               (3 << MXC_CCM_CCGR0_DTCP_OFFSET)
 +#endif
  
  #define MXC_CCM_CCGR1_ECSPI1S_OFFSET                  0
  #define MXC_CCM_CCGR1_ECSPI1S_MASK                    (3 << MXC_CCM_CCGR1_ECSPI1S_OFFSET)
  #define MXC_CCM_CCGR1_ECSPI4S_MASK                    (3 << MXC_CCM_CCGR1_ECSPI4S_OFFSET)
  #define MXC_CCM_CCGR1_ECSPI5S_OFFSET                  8
  #define MXC_CCM_CCGR1_ECSPI5S_MASK                    (3 << MXC_CCM_CCGR1_ECSPI5S_OFFSET)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR1_ENET_CLK_ENABLE_OFFSET          10
  #define MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK            (3 << MXC_CCM_CCGR1_ENET_CLK_ENABLE_OFFSET)
 +#endif
  #define MXC_CCM_CCGR1_EPIT1S_OFFSET                   12
  #define MXC_CCM_CCGR1_EPIT1S_MASK                     (3 << MXC_CCM_CCGR1_EPIT1S_OFFSET)
  #define MXC_CCM_CCGR1_EPIT2S_OFFSET                   14
  #define MXC_CCM_CCGR1_EPIT2S_MASK                     (3 << MXC_CCM_CCGR1_EPIT2S_OFFSET)
  #define MXC_CCM_CCGR1_ESAIS_OFFSET                    16
  #define MXC_CCM_CCGR1_ESAIS_MASK                      (3 << MXC_CCM_CCGR1_ESAIS_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR1_WAKEUP_OFFSET                   18
 +#define MXC_CCM_CCGR1_WAKEUP_MASK                     (3 << MXC_CCM_CCGR1_WAKEUP_OFFSET)
 +#endif
  #define MXC_CCM_CCGR1_GPT_BUS_OFFSET                  20
  #define MXC_CCM_CCGR1_GPT_BUS_MASK                    (3 << MXC_CCM_CCGR1_GPT_BUS_OFFSET)
  #define MXC_CCM_CCGR1_GPT_SERIAL_OFFSET                       22
  #define MXC_CCM_CCGR1_GPT_SERIAL_MASK                 (3 << MXC_CCM_CCGR1_GPT_SERIAL_OFFSET)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR1_GPU2D_OFFSET                    24
  #define MXC_CCM_CCGR1_GPU2D_MASK                      (3 << MXC_CCM_CCGR1_GPU2D_OFFSET)
 +#endif
  #define MXC_CCM_CCGR1_GPU3D_OFFSET                    26
  #define MXC_CCM_CCGR1_GPU3D_MASK                      (3 << MXC_CCM_CCGR1_GPU3D_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR1_OCRAM_S_OFFSET                  28
 +#define MXC_CCM_CCGR1_OCRAM_S_MASK                    (3 << MXC_CCM_CCGR1_OCRAM_S_OFFSET)
 +#define MXC_CCM_CCGR1_CANFD_OFFSET                    30
 +#define MXC_CCM_CCGR1_CANFD_MASK                      (3 << MXC_CCM_CCGR1_CANFD_OFFSET)
 +#endif
  
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_OFFSET          0
  #define MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK            (3 << MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_OFFSET)
 +#else
 +#define MXC_CCM_CCGR2_CSI_OFFSET                      2
 +#define MXC_CCM_CCGR2_CSI_MASK                                (3 << MXC_CCM_CCGR2_CSI_OFFSET)
 +#endif
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_OFFSET          4
  #define MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK            (3 << MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_OFFSET)
 +#endif
  #define MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET              6
  #define MXC_CCM_CCGR2_I2C1_SERIAL_MASK                        (3 << MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET)
  #define MXC_CCM_CCGR2_I2C2_SERIAL_OFFSET              8
  #define MXC_CCM_CCGR2_IPMUX3_MASK                     (3 << MXC_CCM_CCGR2_IPMUX3_OFFSET)
  #define MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC1_IPGS_OFFSET        22
  #define MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC1_IPGS_MASK  (3 << MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC1_IPGS_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR2_LCD_OFFSET                      28
 +#define MXC_CCM_CCGR2_LCD_MASK                                (3 << MXC_CCM_CCGR2_LCD_OFFSET)
 +#define MXC_CCM_CCGR2_PXP_OFFSET                      30
 +#define MXC_CCM_CCGR2_PXP_MASK                                (3 << MXC_CCM_CCGR2_PXP_OFFSET)
 +#else
  #define MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC2_IPG_OFFSET 24
  #define MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC2_IPG_MASK   (3 << MXC_CCM_CCGR2_IPSYNC_IP2APB_TZASC2_IPG_OFFSET)
  #define MXC_CCM_CCGR2_IPSYNC_VDOA_IPG_MASTER_CLK_OFFSET       26
  #define MXC_CCM_CCGR2_IPSYNC_VDOA_IPG_MASTER_CLK_MASK (3 << MXC_CCM_CCGR2_IPSYNC_VDOA_IPG_MASTER_CLK_OFFSET)
 +#endif
  
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR3_M4_OFFSET                                       2
 +#define MXC_CCM_CCGR3_M4_MASK                                 (3 << MXC_CCM_CCGR3_M4_OFFSET)
 +#define MXC_CCM_CCGR3_ENET_OFFSET                             4
 +#define MXC_CCM_CCGR3_ENET_MASK                                       (3 << MXC_CCM_CCGR3_ENET_OFFSET)
 +#define MXC_CCM_CCGR3_QSPI_OFFSET                             14
 +#define MXC_CCM_CCGR3_QSPI_MASK                                       (3 << MXC_CCM_CCGR3_QSPI_OFFSET)
 +#else
  #define MXC_CCM_CCGR3_IPU1_IPU_OFFSET                         0
  #define MXC_CCM_CCGR3_IPU1_IPU_MASK                           (3 << MXC_CCM_CCGR3_IPU1_IPU_OFFSET)
  #define MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET                     2
  #define MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK                               (3 << MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET)
  #define MXC_CCM_CCGR3_IPU1_IPU_DI1_OFFSET                     4
  #define MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK                               (3 << MXC_CCM_CCGR3_IPU1_IPU_DI1_OFFSET)
 +#endif
  #define MXC_CCM_CCGR3_IPU2_IPU_OFFSET                         6
  #define MXC_CCM_CCGR3_IPU2_IPU_MASK                           (3 << MXC_CCM_CCGR3_IPU2_IPU_OFFSET)
  #define MXC_CCM_CCGR3_IPU2_IPU_DI0_OFFSET                     8
  #define MXC_CCM_CCGR3_IPU2_IPU_DI1_MASK                               (3 << MXC_CCM_CCGR3_IPU2_IPU_DI1_OFFSET)
  #define MXC_CCM_CCGR3_LDB_DI0_OFFSET                          12
  #define MXC_CCM_CCGR3_LDB_DI0_MASK                            (3 << MXC_CCM_CCGR3_LDB_DI0_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR3_QSPI1_OFFSET                            14
 +#define MXC_CCM_CCGR3_QSPI1_MASK                              (3 << MXC_CCM_CCGR3_QSPI1_OFFSET)
 +#else
  #define MXC_CCM_CCGR3_LDB_DI1_OFFSET                          14
  #define MXC_CCM_CCGR3_LDB_DI1_MASK                            (3 << MXC_CCM_CCGR3_LDB_DI1_OFFSET)
  #define MXC_CCM_CCGR3_MIPI_CORE_CFG_OFFSET                    16
  #define MXC_CCM_CCGR3_MIPI_CORE_CFG_MASK                      (3 << MXC_CCM_CCGR3_MIPI_CORE_CFG_OFFSET)
 +#endif
  #define MXC_CCM_CCGR3_MLB_OFFSET                              18
  #define MXC_CCM_CCGR3_MLB_MASK                                        (3 << MXC_CCM_CCGR3_MLB_OFFSET)
  #define MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P0_OFFSET      20
  #define MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P0_MASK                (3 << MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P0_OFFSET)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P1_OFFSET      22
  #define MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P1_MASK                (3 << MXC_CCM_CCGR3_MMDC_CORE_ACLK_FAST_CORE_P1_OFFSET)
 +#endif
  #define MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P0_OFFSET             24
  #define MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P0_MASK                       (3 << MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P0_OFFSET)
  #define MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P1_OFFSET             26
  #define MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P1_MASK                       (3 << MXC_CCM_CCGR3_MMDC_CORE_IPG_CLK_P1_OFFSET)
  #define MXC_CCM_CCGR3_OCRAM_OFFSET                            28
  #define MXC_CCM_CCGR3_OCRAM_MASK                              (3 << MXC_CCM_CCGR3_OCRAM_OFFSET)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR3_OPENVGAXICLK_OFFSET                     30
  #define MXC_CCM_CCGR3_OPENVGAXICLK_MASK                               (3 << MXC_CCM_CCGR3_OPENVGAXICLK_OFFSET)
 +#endif
  
  #define MXC_CCM_CCGR4_PCIE_OFFSET                             0
  #define MXC_CCM_CCGR4_PCIE_MASK                                       (3 << MXC_CCM_CCGR4_PCIE_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR4_QSPI2_ENFC_OFFSET                               10
 +#define MXC_CCM_CCGR4_QSPI2_ENFC_MASK                         (3 << MXC_CCM_CCGR4_QSPI2_ENFC_OFFSET)
 +#else
  #define MXC_CCM_CCGR4_PL301_MX6QFAST1_S133_OFFSET             8
  #define MXC_CCM_CCGR4_PL301_MX6QFAST1_S133_MASK                       (3 << MXC_CCM_CCGR4_PL301_MX6QFAST1_S133_OFFSET)
 +#endif
  #define MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET                       12
  #define MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK                 (3 << MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET)
  #define MXC_CCM_CCGR4_PL301_MX6QPER2_MAINCLK_ENABLE_OFFSET    14
  
  #define MXC_CCM_CCGR5_ROM_OFFSET                      0
  #define MXC_CCM_CCGR5_ROM_MASK                                (3 << MXC_CCM_CCGR5_ROM_OFFSET)
 +#ifndef CONFIG_MX6SX
  #define MXC_CCM_CCGR5_SATA_OFFSET                     4
  #define MXC_CCM_CCGR5_SATA_MASK                               (3 << MXC_CCM_CCGR5_SATA_OFFSET)
 +#endif
  #define MXC_CCM_CCGR5_SDMA_OFFSET                     6
  #define MXC_CCM_CCGR5_SDMA_MASK                               (3 << MXC_CCM_CCGR5_SDMA_OFFSET)
  #define MXC_CCM_CCGR5_SPBA_OFFSET                     12
  #define MXC_CCM_CCGR5_UART_MASK                               (3 << MXC_CCM_CCGR5_UART_OFFSET)
  #define MXC_CCM_CCGR5_UART_SERIAL_OFFSET              26
  #define MXC_CCM_CCGR5_UART_SERIAL_MASK                        (3 << MXC_CCM_CCGR5_UART_SERIAL_OFFSET)
 +#ifdef CONFIG_MX6SX
 +#define MXC_CCM_CCGR5_SAI1_OFFSET                     20
 +#define MXC_CCM_CCGR5_SAI1_MASK                               (3 << MXC_CCM_CCGR5_SAI1_OFFSET)
 +#define MXC_CCM_CCGR5_SAI2_OFFSET                     30
 +#define MXC_CCM_CCGR5_SAI2_MASK                               (3 << MXC_CCM_CCGR5_SAI2_OFFSET)
 +#endif
  
- #define MXC_CCM_CCGR6_USBOH3_OFFSET           0
- #define MXC_CCM_CCGR6_USBOH3_MASK             (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
- #define MXC_CCM_CCGR6_USDHC1_OFFSET           2
- #define MXC_CCM_CCGR6_USDHC1_MASK             (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
- #define MXC_CCM_CCGR6_USDHC2_OFFSET           4
- #define MXC_CCM_CCGR6_USDHC2_MASK             (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
- #define MXC_CCM_CCGR6_USDHC3_OFFSET           6
- #define MXC_CCM_CCGR6_USDHC3_MASK             (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
- #define MXC_CCM_CCGR6_USDHC4_OFFSET           8
- #define MXC_CCM_CCGR6_USDHC4_MASK             (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
- #define MXC_CCM_CCGR6_EMI_SLOW_OFFSET         10
- #define MXC_CCM_CCGR6_EMI_SLOW_MASK           (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
+ #define MXC_CCM_CCGR6_USBOH3_OFFSET                   0
+ #define MXC_CCM_CCGR6_USBOH3_MASK                     (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
+ #define MXC_CCM_CCGR6_USDHC1_OFFSET                   2
+ #define MXC_CCM_CCGR6_USDHC1_MASK                     (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
+ #define MXC_CCM_CCGR6_USDHC2_OFFSET                   4
+ #define MXC_CCM_CCGR6_USDHC2_MASK                     (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
+ #define MXC_CCM_CCGR6_USDHC3_OFFSET                   6
+ #define MXC_CCM_CCGR6_USDHC3_MASK                     (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
+ #define MXC_CCM_CCGR6_USDHC4_OFFSET                   8
+ #define MXC_CCM_CCGR6_USDHC4_MASK                     (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
+ #define MXC_CCM_CCGR6_EMI_SLOW_OFFSET                 10
+ #define MXC_CCM_CCGR6_EMI_SLOW_MASK                   (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
+ #define MXC_CCM_CCGR6_VDOAXICLK_OFFSET                        12
+ #define MXC_CCM_CCGR6_VDOAXICLK_MASK                  (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
+ #define ANATOP_PFD_480_PFD0_FRAC_SHIFT                        0
+ #define ANATOP_PFD_480_PFD0_FRAC_MASK                 (0x3f << ANATOP_PFD_480_PFD0_FRAC_SHIFT)
+ #define ANATOP_PFD_480_PFD0_STABLE_SHIFT              6
+ #define ANATOP_PFD_480_PFD0_STABLE_MASK                       (1 << ANATOP_PFD_480_PFD0_STABLE_SHIFT)
+ #define ANATOP_PFD_480_PFD0_CLKGATE_SHIFT             7
+ #define ANATOP_PFD_480_PFD0_CLKGATE_MASK              (1 << ANATOP_PFD_480_PFD0_CLKGATE_SHIFT)
+ #define ANATOP_PFD_480_PFD1_FRAC_SHIFT                        8
+ #define ANATOP_PFD_480_PFD1_FRAC_MASK                 (0x3f << ANATOP_PFD_480_PFD1_FRAC_SHIFT)
+ #define ANATOP_PFD_480_PFD1_STABLE_SHIFT              14
+ #define ANATOP_PFD_480_PFD1_STABLE_MASK                       (1 << ANATOP_PFD_480_PFD1_STABLE_SHIFT)
+ #define ANATOP_PFD_480_PFD1_CLKGATE_SHIFT             15
+ #define ANATOP_PFD_480_PFD1_CLKGATE_MASK              (0x3f << ANATOP_PFD_480_PFD1_CLKGATE_SHIFT)
+ #define ANATOP_PFD_480_PFD2_FRAC_SHIFT                        16
+ #define ANATOP_PFD_480_PFD2_FRAC_MASK                 (1 << ANATOP_PFD_480_PFD2_FRAC_SHIFT)
+ #define ANATOP_PFD_480_PFD2_STABLE_SHIFT              22
+ #define ANATOP_PFD_480_PFD2_STABLE_MASK                       (1 << ANATOP_PFD_480_PFD2_STABLE_SHIFT)
+ #define ANATOP_PFD_480_PFD2_CLKGATE_SHIFT             23
+ #define ANATOP_PFD_480_PFD2_CLKGATE_MASK              (0x3f << ANATOP_PFD_480_PFD2_CLKGATE_SHIFT)
+ #define ANATOP_PFD_480_PFD3_FRAC_SHIFT                        24
+ #define ANATOP_PFD_480_PFD3_FRAC_MASK                 (1 << ANATOP_PFD_480_PFD3_FRAC_SHIFT)
+ #define ANATOP_PFD_480_PFD3_STABLE_SHIFT              30
+ #define ANATOP_PFD_480_PFD3_STABLE_MASK                       (1 << ANATOP_PFD_480_PFD3_STABLE_SHIFT)
+ #define ANATOP_PFD_480_PFD3_CLKGATE_SHIFT             31
+ #define BM_ANADIG_PLL_ARM_LOCK                                (1 << 31)
+ #define BM_ANADIG_PLL_ARM_PLL_SEL                     (1 << 19)
+ #define BM_ANADIG_PLL_ARM_LVDS_24MHZ_SEL              (1 << 18)
+ #define BM_ANADIG_PLL_ARM_LVDS_SEL                    (1 << 17)
+ #define BM_ANADIG_PLL_ARM_BYPASS                      (1 << 16)
+ #define BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC              14
+ #define BM_ANADIG_PLL_ARM_BYPASS_CLK_SRC              (0x3 << BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC)
 -#define BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(v)                           \
 -      (((v) << BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC) & BM_ANADIG_PLL_ARM_BYPASS_CLK_SRC)
 -#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__OSC_24M     BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(0)
 -#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_1    BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(1)
 -#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_2    BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(2)
 -#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__XOR         BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(3)
++#define BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_ARM_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__OSC_24M     0x0
++#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_1    0x1
++#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_2    0x2
++#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__XOR         0x3
+ #define BM_ANADIG_PLL_ARM_ENABLE                      (1 << 13)
+ #define BM_ANADIG_PLL_ARM_POWERDOWN                   (1 << 12)
+ #define BM_ANADIG_PLL_ARM_HOLD_RING_OFF                       (1 << 11)
+ #define BM_ANADIG_PLL_ARM_DOUBLE_CP                   (1 << 10)
+ #define BM_ANADIG_PLL_ARM_HALF_CP                     (1 << 9)
+ #define BM_ANADIG_PLL_ARM_DOUBLE_LF                   (1 << 8)
+ #define BM_ANADIG_PLL_ARM_HALF_LF                     (1 << 7)
+ #define BP_ANADIG_PLL_ARM_DIV_SELECT                  0
+ #define BM_ANADIG_PLL_ARM_DIV_SELECT                  (0x7F << BP_ANADIG_PLL_ARM_DIV_SELECT)
 -#define BF_ANADIG_PLL_ARM_DIV_SELECT(v)                       \
 -      (((v) << BP_ANADIG_PLL_ARM_DIV_SELECT) &        \
++#define BF_ANADIG_PLL_ARM_DIV_SELECT(v)                \
++      (((v) << BP_ANADIG_PLL_ARM_DIV_SELECT) & \
+               BM_ANADIG_PLL_ARM_DIV_SELECT)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_LOCK              (1 << 31)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS            (1 << 16)
 -#define BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC    14
 -#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC    (0x3 << BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC)
 -#define BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(v)                 \
 -      (((v) << BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC) &          \
 -              BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC)
 -#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M   BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(0)
 -#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1  BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(1)
 -#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2  BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(2)
 -#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__XOR               BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(3)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_ENABLE            (1 << 13)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_POWER             (1 << 12)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_HOLD_RING_OFF     (1 << 11)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_CP         (1 << 10)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_CP           (1 << 9)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_LF         (1 << 8)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_LF           (1 << 7)
 -#define BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS               (1 << 6)
 -#define BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0          2
 -#define BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0          (0x7 << BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0)
 -#define BF_ANADIG_USB1_PLL_480_CTRL_CONTROL0(v)                       \
 -      (((v) << BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0) &        \
 -              BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0)
 -#define BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT                0
 -#define BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT                (0x3 << BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT)
 -#define BF_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT(v)             \
 -      (((v) << BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT) &      \
 -              BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT)
 -
 -#define BM_ANADIG_USB2_PLL_480_CTRL_LOCK              (1 << 31)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_BYPASS            (1 << 16)
 -#define BP_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC    14
 -#define BM_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC    (0x3 << BP_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC)
 -#define BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(v)         \
 -      (((v) << BP_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC) &  \
 -              BM_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC)
 -#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M   BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(0)
 -#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1  BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(1)
 -#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2  BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(2)
 -#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__XOR               BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(3)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_ENABLE            (1 << 13)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_POWER             (1 << 12)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_HOLD_RING_OFF     (1 << 11)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_DOUBLE_CP         (1 << 10)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_HALF_CP           (1 << 9)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_DOUBLE_LF         (1 << 8)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_HALF_LF           (1 << 7)
 -#define BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS               (1 << 6)
 -#define BP_ANADIG_USB2_PLL_480_CTRL_CONTROL0          2
 -#define BM_ANADIG_USB2_PLL_480_CTRL_CONTROL0          (0x7 << BP_ANADIG_USB2_PLL_480_CTRL_CONTROL0)
 -#define BF_ANADIG_USB2_PLL_480_CTRL_CONTROL0(v)                       \
 -      (((v) << BP_ANADIG_USB2_PLL_480_CTRL_CONTROL0) &        \
 -              BM_ANADIG_USB2_PLL_480_CTRL_CONTROL0)
 -#define BP_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT                0
 -#define BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT                (0x3 << BP_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT)
 -#define BF_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT(v)             \
 -      (((v) << BP_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT) &      \
 -              BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT)
 -
 -#define BM_ANADIG_PLL_SYS_LOCK                                (1 << 31)
 -#define BM_ANADIG_PLL_SYS_PLL_SEL                     (1 << 19)
 -#define BM_ANADIG_PLL_SYS_LVDS_24MHZ_SEL              (1 << 18)
 -#define BM_ANADIG_PLL_SYS_LVDS_SEL                    (1 << 17)
 -#define BM_ANADIG_PLL_SYS_BYPASS                      (1 << 16)
 -#define BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC              14
 -#define BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC              (0x3 << BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC)
 -#define BF_ANADIG_PLL_SYS_BYPASS_CLK_SRC(v)                           \
 -      (((v) << BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC) & BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC)
 -#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__OSC_24M     0x0
 -#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_1    0x1
 -#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_2    0x2
 -#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__XOR         0x3
 -#define BM_ANADIG_PLL_SYS_ENABLE                      (1 << 13)
 -#define BM_ANADIG_PLL_SYS_POWERDOWN                   (1 << 12)
 -#define BM_ANADIG_PLL_SYS_HOLD_RING_OFF                       (1 << 11)
 -#define BM_ANADIG_PLL_SYS_DOUBLE_CP                   (1 << 10)
 -#define BM_ANADIG_PLL_SYS_HALF_CP                     (1 << 9)
 -#define BM_ANADIG_PLL_SYS_DOUBLE_LF                   (1 << 8)
 -#define BM_ANADIG_PLL_SYS_HALF_LF                     (1 << 7)
 -#define BP_ANADIG_PLL_SYS_DIV_SELECT                  0
 -#define BM_ANADIG_PLL_SYS_DIV_SELECT                  (0x7F << BP_ANADIG_PLL_SYS_DIV_SELECT)
 -#define BF_ANADIG_PLL_SYS_DIV_SELECT(v)                                       \
 -      (((v) << BP_ANADIG_PLL_SYS_DIV_SELECT) & BM_ANADIG_PLL_SYS_DIV_SELECT)
++#define BM_ANADIG_PLL_528_CTRL_LOCK                   (1 << 31)
++#define BM_ANADIG_PLL_528_PFD_OFFSET_EN                       (1 << 18)
++#define BM_ANADIG_PLL_528_DITHER_ENABLE                       (1 << 17)
++#define BM_ANADIG_PLL_528_CTRL_BYPASS                 (1 << 16)
++#define BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC         14
++#define BM_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC         (0x3 << BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__OSC_24M        0x0
++#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__ANACLK_1       0x1
++#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__ANACLK_2       0x2
++#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__XOR    0x3
++#define BM_ANADIG_PLL_528_CTRL_ENABLE                 (1 << 13)
++#define BM_ANADIG_PLL_528_CTRL_POWER                  (1 << 12)
++#define BM_ANADIG_PLL_528_CTRL_HOLD_RING_OFF          (1 << 11)
++#define BM_ANADIG_PLL_528_CTRL_DOUBLE_CP              (1 << 10)
++#define BM_ANADIG_PLL_528_CTRL_HALF_CP                        (1 << 9)
++#define BM_ANADIG_PLL_528_CTRL_DOUBLE_LF              (1 << 8)
++#define BM_ANADIG_PLL_528_CTRL_HALF_LF                        (1 << 7)
++#define BM_ANADIG_PLL_528_CTRL_EN_USB_CLKS            (1 << 6)
++#define BP_ANADIG_PLL_528_CTRL_CONTROL0                       2
++#define BM_ANADIG_PLL_528_CTRL_CONTROL0                       (0x7 << BP_ANADIG_PLL_528_CTRL_CONTROL0)
++#define BF_ANADIG_PLL_528_CTRL_CONTROL0(v)            \
++      (((v) << BP_ANADIG_PLL_528_CTRL_CONTROL0) &     \
++              BM_ANADIG_PLL_528_CTRL_CONTROL0)
++#define BP_ANADIG_PLL_528_CTRL_DIV_SELECT             0
++#define BM_ANADIG_PLL_528_CTRL_DIV_SELECT             (0x3 << BP_ANADIG_PLL_528_CTRL_DIV_SELECT)
++#define BF_ANADIG_PLL_528_CTRL_DIV_SELECT(v)          \
++      (((v) << BP_ANADIG_PLL_528_CTRL_DIV_SELECT) &   \
++              BM_ANADIG_PLL_528_CTRL_DIV_SELECT)
+ #define BM_ANADIG_PLL_AUDIO_LOCK                      (1 << 31)
+ #define BM_ANADIG_PLL_AUDIO_SSC_EN                    (1 << 21)
+ #define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT           19
+ #define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT           (0x3 << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+ #define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)                                \
+       (((v) << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+ #define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN             (1 << 18)
+ #define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE             (1 << 17)
+ #define BM_ANADIG_PLL_AUDIO_BYPASS                    (1 << 16)
+ #define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC            14
+ #define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC            (0x3 << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
 -#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)         \
++#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)                         \
+       (((v) << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC) & BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+ #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M   0x0
+ #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1  0x1
+ #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2  0x2
+ #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR               0x3
+ #define BM_ANADIG_PLL_AUDIO_ENABLE                    (1 << 13)
+ #define BM_ANADIG_PLL_AUDIO_POWERDOWN                 (1 << 12)
+ #define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF             (1 << 11)
+ #define BM_ANADIG_PLL_AUDIO_DOUBLE_CP                 (1 << 10)
+ #define BM_ANADIG_PLL_AUDIO_HALF_CP                   (1 << 9)
+ #define BM_ANADIG_PLL_AUDIO_DOUBLE_LF                 (1 << 8)
+ #define BM_ANADIG_PLL_AUDIO_HALF_LF                   (1 << 7)
+ #define BP_ANADIG_PLL_AUDIO_DIV_SELECT                        0
+ #define BM_ANADIG_PLL_AUDIO_DIV_SELECT                        (0x7F << BP_ANADIG_PLL_AUDIO_DIV_SELECT)
 -#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)                             \
 -      (((v) << BP_ANADIG_PLL_AUDIO_DIV_SELECT) & BM_ANADIG_PLL_AUDIO_DIV_SELECT)
++#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_AUDIO_DIV_SELECT) & \
++              BM_ANADIG_PLL_AUDIO_DIV_SELECT)
+ #define BP_ANADIG_PLL_AUDIO_NUM_A                     0
 -#define BM_ANADIG_PLL_AUDIO_NUM_A                     0x3FFFFFFF
 -#define BF_ANADIG_PLL_AUDIO_NUM_A(v)                                  \
 -      (((v) << BP_ANADIG_PLL_AUDIO_NUM_A) & BM_ANADIG_PLL_AUDIO_NUM_A)
++#define BM_ANADIG_PLL_AUDIO_NUM_A                     (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_NUM_A)
++#define BF_ANADIG_PLL_AUDIO_NUM_A(v)        \
++      (((v) << BP_ANADIG_PLL_AUDIO_NUM_A) & \
++              BM_ANADIG_PLL_AUDIO_NUM_A)
+ #define BP_ANADIG_PLL_AUDIO_DENOM_B                   0
 -#define BM_ANADIG_PLL_AUDIO_DENOM_B                   0x3FFFFFFF
 -#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)                                        \
 -      (((v) << BP_ANADIG_PLL_AUDIO_DENOM_B) & BM_ANADIG_PLL_AUDIO_DENOM_B)
++#define BM_ANADIG_PLL_AUDIO_DENOM_B                   (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_DENOM_B)
++#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)                \
++      (((v) << BP_ANADIG_PLL_AUDIO_DENOM_B) & \
++              BM_ANADIG_PLL_AUDIO_DENOM_B)
+ #define BM_ANADIG_PLL_VIDEO_LOCK                      (1 << 31)
+ #define BM_ANADIG_PLL_VIDEO_SSC_EN                    (1 << 21)
+ #define BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT           19
+ #define BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT           (0x3 << BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
 -#define BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(v)                                \
 -      (((v) << BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT) & BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
++#define BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(v)                \
++      (((v) << BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT) & \
++              BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
+ #define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN             (1 << 18)
+ #define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE             (1 << 17)
+ #define BM_ANADIG_PLL_VIDEO_BYPASS                    (1 << 16)
+ #define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC            14
+ #define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC            (0x3 << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
 -#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)                         \
 -      (((v) << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC) & BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+ #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M   0x0
+ #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1  0x1
+ #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2  0x2
+ #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR               0x3
+ #define BM_ANADIG_PLL_VIDEO_ENABLE                    (1 << 13)
+ #define BM_ANADIG_PLL_VIDEO_POWERDOWN                 (1 << 12)
+ #define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF             (1 << 11)
+ #define BM_ANADIG_PLL_VIDEO_DOUBLE_CP                 (1 << 10)
+ #define BM_ANADIG_PLL_VIDEO_HALF_CP                   (1 << 9)
+ #define BM_ANADIG_PLL_VIDEO_DOUBLE_LF                 (1 << 8)
+ #define BM_ANADIG_PLL_VIDEO_HALF_LF                   (1 << 7)
+ #define BP_ANADIG_PLL_VIDEO_DIV_SELECT                        0
+ #define BM_ANADIG_PLL_VIDEO_DIV_SELECT                        (0x7F << BP_ANADIG_PLL_VIDEO_DIV_SELECT)
 -#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)                             \
 -      (((v) << BP_ANADIG_PLL_VIDEO_DIV_SELECT) & BM_ANADIG_PLL_VIDEO_DIV_SELECT)
++#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_DIV_SELECT) & \
++              BM_ANADIG_PLL_VIDEO_DIV_SELECT)
+ #define BP_ANADIG_PLL_VIDEO_NUM_A                     0
+ #define BM_ANADIG_PLL_VIDEO_NUM_A                     (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_NUM_A)
 -#define BF_ANADIG_PLL_VIDEO_NUM_A(v)                                  \
 -      (((v) << BP_ANADIG_PLL_VIDEO_NUM_A) & BM_ANADIG_PLL_VIDEO_NUM_A)
++#define BF_ANADIG_PLL_VIDEO_NUM_A(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_NUM_A) & \
++              BM_ANADIG_PLL_VIDEO_NUM_A)
+ #define BP_ANADIG_PLL_VIDEO_DENOM_B                   0
+ #define BM_ANADIG_PLL_VIDEO_DENOM_B                   (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_DENOM_B)
 -#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)                                        \
 -      (((v) << BP_ANADIG_PLL_VIDEO_DENOM_B) & BM_ANADIG_PLL_VIDEO_DENOM_B)
++#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)                \
++      (((v) << BP_ANADIG_PLL_VIDEO_DENOM_B) & \
++              BM_ANADIG_PLL_VIDEO_DENOM_B)
+ #define BM_ANADIG_PLL_MLB_LOCK                                (1 << 31)
+ #define BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG         26
+ #define BM_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG         (0x7 << BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG)
 -#define BF_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG(v)                      \
 -      (((v) << BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG) & BM_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG)
++#define BF_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG(v)        \
++      (((v) << BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG) & \
++              BM_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG)
+ #define BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG              23
+ #define BM_ANADIG_PLL_MLB_RX_CLK_DLY_CFG              (0x7 << BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG)
 -#define BF_ANADIG_PLL_MLB_RX_CLK_DLY_CFG(v)                           \
 -      (((v) << BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG) & BM_ANADIG_PLL_MLB_RX_CLK_DLY_CFG)
++#define BF_ANADIG_PLL_MLB_RX_CLK_DLY_CFG(v)        \
++      (((v) << BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG) & \
++              BM_ANADIG_PLL_MLB_RX_CLK_DLY_CFG)
+ #define BP_ANADIG_PLL_MLB_VDDD_DLY_CFG                        20
+ #define BM_ANADIG_PLL_MLB_VDDD_DLY_CFG                        (0x7 << BP_ANADIG_PLL_MLB_VDDD_DLY_CFG)
 -#define BF_ANADIG_PLL_MLB_VDDD_DLY_CFG(v)                             \
 -      (((v) << BP_ANADIG_PLL_MLB_VDDD_DLY_CFG) & BM_ANADIG_PLL_MLB_VDDD_DLY_CFG)
++#define BF_ANADIG_PLL_MLB_VDDD_DLY_CFG(v)        \
++      (((v) << BP_ANADIG_PLL_MLB_VDDD_DLY_CFG) & \
++              BM_ANADIG_PLL_MLB_VDDD_DLY_CFG)
+ #define BP_ANADIG_PLL_MLB_VDDA_DLY_CFG                        17
+ #define BM_ANADIG_PLL_MLB_VDDA_DLY_CFG                        (0x7 << BP_ANADIG_PLL_MLB_VDDA_DLY_CFG)
 -#define BF_ANADIG_PLL_MLB_VDDA_DLY_CFG(v)                             \
 -      (((v) << BP_ANADIG_PLL_MLB_VDDA_DLY_CFG) & BM_ANADIG_PLL_MLB_VDDA_DLY_CFG)
++#define BF_ANADIG_PLL_MLB_VDDA_DLY_CFG(v)        \
++      (((v) << BP_ANADIG_PLL_MLB_VDDA_DLY_CFG) & \
++              BM_ANADIG_PLL_MLB_VDDA_DLY_CFG)
+ #define BM_ANADIG_PLL_MLB_BYPASS                      (1 << 16)
+ #define BP_ANADIG_PLL_MLB_PHASE_SEL                   12
+ #define BM_ANADIG_PLL_MLB_PHASE_SEL                   (0x7 << BP_ANADIG_PLL_MLB_PHASE_SEL)
 -#define BF_ANADIG_PLL_MLB_PHASE_SEL(v)                                \
 -      (((v) << BP_ANADIG_PLL_MLB_PHASE_SEL) & BM_ANADIG_PLL_MLB_PHASE_SEL)
++#define BF_ANADIG_PLL_MLB_PHASE_SEL(v)                \
++      (((v) << BP_ANADIG_PLL_MLB_PHASE_SEL) & \
++              BM_ANADIG_PLL_MLB_PHASE_SEL)
+ #define BM_ANADIG_PLL_MLB_HOLD_RING_OFF                       (1 << 11)
+ #define BM_ANADIG_PLL_ENET_LOCK                               (1 << 31)
+ #define BM_ANADIG_PLL_ENET_ENABLE_SATA                        (1 << 20)
+ #define BM_ANADIG_PLL_ENET_ENABLE_PCIE                        (1 << 19)
+ #define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN              (1 << 18)
+ #define BM_ANADIG_PLL_ENET_DITHER_ENABLE              (1 << 17)
+ #define BM_ANADIG_PLL_ENET_BYPASS                     (1 << 16)
+ #define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC             14
+ #define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
 -#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)                          \
 -      (((v) << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC) & BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+ #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M    0x0
+ #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1   0x1
+ #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2   0x2
+ #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR                0x3
+ #define BM_ANADIG_PLL_ENET_ENABLE                     (1 << 13)
+ #define BM_ANADIG_PLL_ENET_POWERDOWN                  (1 << 12)
+ #define BM_ANADIG_PLL_ENET_HOLD_RING_OFF              (1 << 11)
+ #define BM_ANADIG_PLL_ENET_DOUBLE_CP                  (1 << 10)
+ #define BM_ANADIG_PLL_ENET_HALF_CP                    (1 << 9)
+ #define BM_ANADIG_PLL_ENET_DOUBLE_LF                  (1 << 8)
+ #define BM_ANADIG_PLL_ENET_HALF_LF                    (1 << 7)
+ #define BP_ANADIG_PLL_ENET_DIV_SELECT                 0
+ #define BM_ANADIG_PLL_ENET_DIV_SELECT                 (0x3 << BP_ANADIG_PLL_ENET_DIV_SELECT)
 -#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)                              \
 -      (((v) << BP_ANADIG_PLL_ENET_DIV_SELECT) & BM_ANADIG_PLL_ENET_DIV_SELECT)
++#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_ENET_DIV_SELECT) & \
++              BM_ANADIG_PLL_ENET_DIV_SELECT)
+ #define BM_ANADIG_PFD_480_PFD3_CLKGATE                        (1 << 31)
+ #define BM_ANADIG_PFD_480_PFD3_STABLE                 (1 << 30)
+ #define BP_ANADIG_PFD_480_PFD3_FRAC                   24
+ #define BM_ANADIG_PFD_480_PFD3_FRAC                   (0x3F << BP_ANADIG_PFD_480_PFD3_FRAC)
+ #define BF_ANADIG_PFD_480_PFD3_FRAC(v)                \
 -      (((v) << BP_ANADIG_PFD_480_PFD3_FRAC) & BM_ANADIG_PFD_480_PFD3_FRAC)
++      (((v) << BP_ANADIG_PFD_480_PFD3_FRAC) & \
++              BM_ANADIG_PFD_480_PFD3_FRAC)
+ #define BP_ANADIG_ANA_MISC0_CLKGATE_DELAY             26
+ #define BM_ANADIG_ANA_MISC0_CLKGATE_DELAY             (0x7 << BP_ANADIG_ANA_MISC0_CLKGATE_DELAY)
 -#define BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(v)                  \
 -      (((v) << BP_ANADIG_ANA_MISC0_CLKGATE_DELAY) & BM_ANADIG_ANA_MISC0_CLKGATE_DELAY)
++#define BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(v)        \
++      (((v) << BP_ANADIG_ANA_MISC0_CLKGATE_DELAY) & \
++              BM_ANADIG_ANA_MISC0_CLKGATE_DELAY)
+ #define BM_ANADIG_ANA_MISC0_CLKGATE_CTRL              (1 << 25)
+ #define BP_ANADIG_ANA_MISC0_ANAMUX                    21
+ #define BM_ANADIG_ANA_MISC0_ANAMUX                    (0xf << BP_ANADIG_ANA_MISC0_ANAMUX)
 -#define BF_ANADIG_ANA_MISC0_ANAMUX(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC0_ANAMUX) & BM_ANADIG_ANA_MISC0_ANAMUX)
++#define BF_ANADIG_ANA_MISC0_ANAMUX(v)        \
++      (((v) << BP_ANADIG_ANA_MISC0_ANAMUX) & \
++              BM_ANADIG_ANA_MISC0_ANAMUX)
+ #define BM_ANADIG_ANA_MISC0_ANAMUX_EN                 (1 << 20)
+ #define BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH           18
+ #define BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH           (0x3 << BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
+ #define BF_ANADIG_ANA_MISC0_WBCP_VPW_THRESH(v)                \
 -      (((v) << BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH) & BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
++      (((v) << BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH) & \
++              BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
+ #define BM_ANADIG_ANA_MISC0_OSC_XTALOK_EN             (1 << 17)
 -#define BM_ANADIG_ANA_MISC0_OSC_XTALOK                (1 << 16)
 -#define BP_ANADIG_ANA_MISC0_OSC_I             14
 -#define BM_ANADIG_ANA_MISC0_OSC_I 0x0000C000
 -#define BF_ANADIG_ANA_MISC0_OSC_I(v)          \
 -      (((v) << BP_ANADIG_ANA_MISC0_OSC_I) & BM_ANADIG_ANA_MISC0_OSC_I)
++#define BM_ANADIG_ANA_MISC0_OSC_XTALOK                        (1 << 16)
++#define BP_ANADIG_ANA_MISC0_OSC_I                     14
++#define BM_ANADIG_ANA_MISC0_OSC_I                     (0x3 << BP_ANADIG_ANA_MISC0_OSC_I)
++#define BF_ANADIG_ANA_MISC0_OSC_I(v)        \
++      (((v) << BP_ANADIG_ANA_MISC0_OSC_I) & \
++              BM_ANADIG_ANA_MISC0_OSC_I)
+ #define BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN            (1 << 13)
 -#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG                  (1 << 12)
++#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG          (1 << 12)
+ #define BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST           8
 -#define BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST 0x00000300
++#define BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST           (0x3 << BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
+ #define BF_ANADIG_ANA_MISC0_REFTOP_BIAS_TST(v)                \
 -      (((v) << BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST) & BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
 -#define BM_ANADIG_ANA_MISC0_REFTOP_VBGUP                      (1 << 7)
++      (((v) << BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST) & \
++              BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
++#define BM_ANADIG_ANA_MISC0_REFTOP_VBGUP              (1 << 7)
+ #define BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ             4
+ #define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ             (0x7 << BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
 -#define BF_ANADIG_ANA_MISC0_REFTOP_VBGADJ(v)          \
 -      (((v) << BM_ANADIG_ANA_MISC0_REFTOP_VBGUP) & BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
 -#define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF                 (1 << 3)
 -#define BM_ANADIG_ANA_MISC0_REFTOP_LOWPOWER                   (1 << 2)
 -#define BM_ANADIG_ANA_MISC0_REFTOP_PWDVBGUP                   (1 << 1)
++#define BF_ANADIG_ANA_MISC0_REFTOP_VBGADJ(v)        \
++      (((v) << BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ) & \
++              BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
++#define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF         (1 << 3)
++#define BM_ANADIG_ANA_MISC0_REFTOP_LOWPOWER           (1 << 2)
++#define BM_ANADIG_ANA_MISC0_REFTOP_PWDVBGUP           (1 << 1)
+ #define BM_ANADIG_ANA_MISC0_REFTOP_PWD                        (1 << 0)
 -#define BM_ANADIG_ANA_MISC1_IRQ_DIG_BO                (1 << 31)
 -#define BM_ANADIG_ANA_MISC1_IRQ_ANA_BO 0x40000000
 -#define BM_ANADIG_ANA_MISC1_IRQ_TEMPSENSE_BO 0x20000000
++#define BM_ANADIG_ANA_MISC1_IRQ_DIG_BO                        (1 << 31)
++#define BM_ANADIG_ANA_MISC1_IRQ_ANA_BO                        (1 << 30)
++#define BM_ANADIG_ANA_MISC1_IRQ_TEMPSENSE_BO          (1 << 29)
+ #define BM_ANADIG_ANA_MISC1_LVDSCLK2_IBEN             (1 << 13)
 -#define BM_ANADIG_ANA_MISC1_LVDSCLK1_IBEN                     (1 << 12)
 -#define BM_ANADIG_ANA_MISC1_LVDSCLK2_OBEN                     (1 << 11)
 -#define BM_ANADIG_ANA_MISC1_LVDSCLK1_OBEN                     (1 << 10)
++#define BM_ANADIG_ANA_MISC1_LVDSCLK1_IBEN             (1 << 12)
++#define BM_ANADIG_ANA_MISC1_LVDSCLK2_OBEN             (1 << 11)
++#define BM_ANADIG_ANA_MISC1_LVDSCLK1_OBEN             (1 << 10)
+ #define BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL             5
 -#define BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL 0x000003E0
 -#define BF_ANADIG_ANA_MISC1_LVDS2_CLK_SEL(v)          \
 -      (((v) << BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL) & BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
++#define BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL             (0x1f << BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
++#define BF_ANADIG_ANA_MISC1_LVDS2_CLK_SEL(v)        \
++      (((v) << BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL) & \
++              BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
+ #define BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL             0
 -#define BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL 0x0000001F
 -#define BF_ANADIG_ANA_MISC1_LVDS1_CLK_SEL(v)          \
 -      (((v) << 0) & BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
 -
 -#define BP_ANADIG_ANA_MISC2_CONTROL3          30
 -#define BM_ANADIG_ANA_MISC2_CONTROL3 0xC0000000
 -#define BF_ANADIG_ANA_MISC2_CONTROL3(v) \
 -      (((v) << BP_ANADIG_ANA_MISC2_CONTROL3) & BM_ANADIG_ANA_MISC2_CONTROL3)
++#define BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL             (0x1F << BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
++#define BF_ANADIG_ANA_MISC1_LVDS1_CLK_SEL(v)        \
++      (((v) << BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL) & \
++              BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
++
++#define BP_ANADIG_ANA_MISC2_CONTROL3                  30
++#define BM_ANADIG_ANA_MISC2_CONTROL3                  (0x3 << BP_ANADIG_ANA_MISC2_CONTROL3)
++#define BF_ANADIG_ANA_MISC2_CONTROL3(v)                \
++      (((v) << BP_ANADIG_ANA_MISC2_CONTROL3) & \
++              BM_ANADIG_ANA_MISC2_CONTROL3)
+ #define BP_ANADIG_ANA_MISC2_REG2_STEP_TIME            28
 -#define BM_ANADIG_ANA_MISC2_REG2_STEP_TIME 0x30000000
 -#define BF_ANADIG_ANA_MISC2_REG2_STEP_TIME(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG2_STEP_TIME) & BM_ANADIG_ANA_MISC2_REG2_STEP_TIME)
++#define BM_ANADIG_ANA_MISC2_REG2_STEP_TIME            (0x3 << BP_ANADIG_ANA_MISC2_REG2_STEP_TIME)
++#define BF_ANADIG_ANA_MISC2_REG2_STEP_TIME(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG2_STEP_TIME) & \
++              BM_ANADIG_ANA_MISC2_REG2_STEP_TIME)
+ #define BP_ANADIG_ANA_MISC2_REG1_STEP_TIME            26
 -#define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME 0x0C000000
 -#define BF_ANADIG_ANA_MISC2_REG1_STEP_TIME(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG1_STEP_TIME) & BM_ANADIG_ANA_MISC2_REG1_STEP_TIME)
++#define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME            (0x3 << BP_ANADIG_ANA_MISC2_REG1_STEP_TIME)
++#define BF_ANADIG_ANA_MISC2_REG1_STEP_TIME(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG1_STEP_TIME) & \
++              BM_ANADIG_ANA_MISC2_REG1_STEP_TIME)
+ #define BP_ANADIG_ANA_MISC2_REG0_STEP_TIME            24
 -#define BM_ANADIG_ANA_MISC2_REG0_STEP_TIME 0x03000000
 -#define BF_ANADIG_ANA_MISC2_REG0_STEP_TIME(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG0_STEP_TIME) & BM_ANADIG_ANA_MISC2_REG0_STEP_TIME)
 -#define BM_ANADIG_ANA_MISC2_CONTROL2 0x00800000
 -#define BM_ANADIG_ANA_MISC2_REG2_OK 0x00400000
 -#define BM_ANADIG_ANA_MISC2_REG2_ENABLE_BO                    (1 << 21)
++#define BM_ANADIG_ANA_MISC2_REG0_STEP_TIME            (0x3 << BP_ANADIG_ANA_MISC2_REG0_STEP_TIME)
++#define BF_ANADIG_ANA_MISC2_REG0_STEP_TIME(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG0_STEP_TIME) & \
++              BM_ANADIG_ANA_MISC2_REG0_STEP_TIME)
++#define BM_ANADIG_ANA_MISC2_CONTROL2                  (1 << 23)
++#define BM_ANADIG_ANA_MISC2_REG2_OK                   (1 << 22)
++#define BM_ANADIG_ANA_MISC2_REG2_ENABLE_BO            (1 << 21)
+ #define BM_ANADIG_ANA_MISC2_REG2_BO_STATUS            (1 << 19)
+ #define BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET            16
 -#define BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET 0x00070000
 -#define BF_ANADIG_ANA_MISC2_REG2_BO_OFFSET(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET) & BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
 -#define BM_ANADIG_ANA_MISC2_CONTROL1          (1 << 15)
 -#define BM_ANADIG_ANA_MISC2_REG1_OK           (1 << 14)
++#define BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET            (0x7 << BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
++#define BF_ANADIG_ANA_MISC2_REG2_BO_OFFSET(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET) & \
++              BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
++#define BM_ANADIG_ANA_MISC2_CONTROL1                  (1 << 15)
++#define BM_ANADIG_ANA_MISC2_REG1_OK                   (1 << 14)
+ #define BM_ANADIG_ANA_MISC2_REG1_ENABLE_BO            (1 << 13)
 -#define BM_ANADIG_ANA_MISC2_REG1_BO_STATUS                    (1 << 11)
++#define BM_ANADIG_ANA_MISC2_REG1_BO_STATUS            (1 << 11)
+ #define BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET            8
 -#define BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET 0x00000700
 -#define BF_ANADIG_ANA_MISC2_REG1_BO_OFFSET(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET) & BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET)
++#define BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET            (0x7 << BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET
++#define BF_ANADIG_ANA_MISC2_REG1_BO_OFFSET(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET) & \
++              BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET)
+ #define BM_ANADIG_ANA_MISC2_CONTROL0                  (1 << 7)
+ #define BM_ANADIG_ANA_MISC2_REG0_OK                   (1 << 6)
+ #define BM_ANADIG_ANA_MISC2_REG0_ENABLE_BO            (1 << 5)
+ #define BM_ANADIG_ANA_MISC2_REG0_BO_STATUS            (1 << 3)
+ #define BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET            0
+ #define BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET            (0x7 << BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
 -#define BF_ANADIG_ANA_MISC2_REG0_BO_OFFSET(v)         \
 -      (((v) << BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET) & BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
 -
 -#define BP_ANADIG_TEMPSENSE0_ALARM_VALUE      20
 -#define BM_ANADIG_TEMPSENSE0_ALARM_VALUE      (0xFFF << BP_ANADIG_TEMPSENSE0_ALARM_VALUE)
 -#define BF_ANADIG_TEMPSENSE0_ALARM_VALUE(v)                   \
 -      (((v) << BP_ANADIG_TEMPSENSE0_ALARM_VALUE) & BM_ANADIG_TEMPSENSE0_ALARM_VALUE)
 -#define BP_ANADIG_TEMPSENSE0_TEMP_VALUE               8
 -#define BM_ANADIG_TEMPSENSE0_TEMP_VALUE               (0xFFF << BP_ANADIG_TEMPSENSE0_TEMP_VALUE)
 -#define BF_ANADIG_TEMPSENSE0_TEMP_VALUE(v)            \
 -      (((v) << BP_ANADIG_TEMPSENSE0_TEMP_VALUE) & BM_ANADIG_TEMPSENSE0_TEMP_VALUE)
 -#define BM_ANADIG_TEMPSENSE0_TEST             (1 << 6)
 -#define BP_ANADIG_TEMPSENSE0_VBGADJ           3
 -#define BM_ANADIG_TEMPSENSE0_VBGADJ           (0x7 << BP_ANADIG_TEMPSENSE0_VBGADJ)
++#define BF_ANADIG_ANA_MISC2_REG0_BO_OFFSET(v)        \
++      (((v) << BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET) & \
++              BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
++
++#define BP_ANADIG_TEMPSENSE0_ALARM_VALUE              20
++#define BM_ANADIG_TEMPSENSE0_ALARM_VALUE              (0xFFF << BP_ANADIG_TEMPSENSE0_ALARM_VALUE)
++#define BF_ANADIG_TEMPSENSE0_ALARM_VALUE(v)        \
++      (((v) << BP_ANADIG_TEMPSENSE0_ALARM_VALUE) & \
++              BM_ANADIG_TEMPSENSE0_ALARM_VALUE)
++#define BP_ANADIG_TEMPSENSE0_TEMP_VALUE                       8
++#define BM_ANADIG_TEMPSENSE0_TEMP_VALUE                       (0xFFF << BP_ANADIG_TEMPSENSE0_TEMP_VALUE)
++#define BF_ANADIG_TEMPSENSE0_TEMP_VALUE(v)        \
++      (((v) << BP_ANADIG_TEMPSENSE0_TEMP_VALUE) & \
++              BM_ANADIG_TEMPSENSE0_TEMP_VALUE)
++#define BM_ANADIG_TEMPSENSE0_TEST                     (1 << 6)
++#define BP_ANADIG_TEMPSENSE0_VBGADJ                   3
++#define BM_ANADIG_TEMPSENSE0_VBGADJ                   (0x7 << BP_ANADIG_TEMPSENSE0_VBGADJ)
+ #define BF_ANADIG_TEMPSENSE0_VBGADJ(v)                \
 -      (((v) << BP_ANADIG_TEMPSENSE0_VBGADJ) & BM_ANADIG_TEMPSENSE0_VBGADJ)
 -#define BM_ANADIG_TEMPSENSE0_FINISHED         (1 << 2)
 -#define BM_ANADIG_TEMPSENSE0_MEASURE_TEMP     (1 << 1)
 -#define BM_ANADIG_TEMPSENSE0_POWER_DOWN               (1 << 0)
 -
 -#define BP_ANADIG_TEMPSENSE1_MEASURE_FREQ     0
 -#define BM_ANADIG_TEMPSENSE1_MEASURE_FREQ     (0xFFFF << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ)
 -#define BF_ANADIG_TEMPSENSE1_MEASURE_FREQ(v)                  \
 -      (((v) << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ) & BM_ANADIG_TEMPSENSE1_MEASURE_FREQ)
 -
 -#ifdef CONFIG_MX6Q
 -#define PLL2_PFD0_FREQ                352000000
 -#define PLL2_PFD1_FREQ                594000000
++      (((v) << BP_ANADIG_TEMPSENSE0_VBGADJ) & \
++              BM_ANADIG_TEMPSENSE0_VBGADJ)
++#define BM_ANADIG_TEMPSENSE0_FINISHED                 (1 << 2)
++#define BM_ANADIG_TEMPSENSE0_MEASURE_TEMP             (1 << 1)
++#define BM_ANADIG_TEMPSENSE0_POWER_DOWN                       (1 << 0)
++
++#define BP_ANADIG_TEMPSENSE1_MEASURE_FREQ             0
++#define BM_ANADIG_TEMPSENSE1_MEASURE_FREQ             (0xFFFF << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ)
++#define BF_ANADIG_TEMPSENSE1_MEASURE_FREQ(v)        \
++      (((v) << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ) & \
++              BM_ANADIG_TEMPSENSE1_MEASURE_FREQ)
++
++#define MXC_CCM_CCGR6_USBOH3_OFFSET                   0
++#define MXC_CCM_CCGR6_USBOH3_MASK                     (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
++#define MXC_CCM_CCGR6_USDHC1_OFFSET                   2
++#define MXC_CCM_CCGR6_USDHC1_MASK                     (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
++#define MXC_CCM_CCGR6_USDHC2_OFFSET                   4
++#define MXC_CCM_CCGR6_USDHC2_MASK                     (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
++#define MXC_CCM_CCGR6_USDHC3_OFFSET                   6
++#define MXC_CCM_CCGR6_USDHC3_MASK                     (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
++#define MXC_CCM_CCGR6_USDHC4_OFFSET                   8
++#define MXC_CCM_CCGR6_USDHC4_MASK                     (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
++#define MXC_CCM_CCGR6_EMI_SLOW_OFFSET                 10
++#define MXC_CCM_CCGR6_EMI_SLOW_MASK                   (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
 +#ifdef CONFIG_MX6SX
- #define MXC_CCM_CCGR6_PWM8_OFFSET             16
- #define MXC_CCM_CCGR6_PWM8_MASK                       (3 << MXC_CCM_CCGR6_PWM8_OFFSET)
- #define MXC_CCM_CCGR6_VADC_OFFSET             20
- #define MXC_CCM_CCGR6_VADC_MASK                       (3 << MXC_CCM_CCGR6_VADC_OFFSET)
- #define MXC_CCM_CCGR6_GIS_OFFSET              22
- #define MXC_CCM_CCGR6_GIS_MASK                        (3 << MXC_CCM_CCGR6_GIS_OFFSET)
- #define MXC_CCM_CCGR6_I2C4_OFFSET             24
- #define MXC_CCM_CCGR6_I2C4_MASK                       (3 << MXC_CCM_CCGR6_I2C4_OFFSET)
- #define MXC_CCM_CCGR6_PWM5_OFFSET             26
- #define MXC_CCM_CCGR6_PWM5_MASK                       (3 << MXC_CCM_CCGR6_PWM5_OFFSET)
- #define MXC_CCM_CCGR6_PWM6_OFFSET             28
- #define MXC_CCM_CCGR6_PWM6_MASK                       (3 << MXC_CCM_CCGR6_PWM6_OFFSET)
- #define MXC_CCM_CCGR6_PWM7_OFFSET             30
- #define MXC_CCM_CCGR6_PWM7_MASK                       (3 << MXC_CCM_CCGR6_PWM7_OFFSET)
++#define MXC_CCM_CCGR6_PWM8_OFFSET                     16
++#define MXC_CCM_CCGR6_PWM8_MASK                               (3 << MXC_CCM_CCGR6_PWM8_OFFSET)
++#define MXC_CCM_CCGR6_VADC_OFFSET                     20
++#define MXC_CCM_CCGR6_VADC_MASK                               (3 << MXC_CCM_CCGR6_VADC_OFFSET)
++#define MXC_CCM_CCGR6_GIS_OFFSET                      22
++#define MXC_CCM_CCGR6_GIS_MASK                                (3 << MXC_CCM_CCGR6_GIS_OFFSET)
++#define MXC_CCM_CCGR6_I2C4_OFFSET                     24
++#define MXC_CCM_CCGR6_I2C4_MASK                               (3 << MXC_CCM_CCGR6_I2C4_OFFSET)
++#define MXC_CCM_CCGR6_PWM5_OFFSET                     26
++#define MXC_CCM_CCGR6_PWM5_MASK                               (3 << MXC_CCM_CCGR6_PWM5_OFFSET)
++#define MXC_CCM_CCGR6_PWM6_OFFSET                     28
++#define MXC_CCM_CCGR6_PWM6_MASK                               (3 << MXC_CCM_CCGR6_PWM6_OFFSET)
++#define MXC_CCM_CCGR6_PWM7_OFFSET                     30
++#define MXC_CCM_CCGR6_PWM7_MASK                               (3 << MXC_CCM_CCGR6_PWM7_OFFSET)
  #else
- #define MXC_CCM_CCGR6_VDOAXICLK_OFFSET                12
- #define MXC_CCM_CCGR6_VDOAXICLK_MASK          (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
 -#define PLL2_PFD0_FREQ                306580000
 -#define PLL2_PFD1_FREQ                528000000
 -#endif
 -#define PLL2_PFD2_FREQ                396000000
 -#define PLL2_PFD2_DIV_FREQ    (PLL2_PFD2_FREQ / 2)
 -#define PLL3_PFD0_FREQ                720000000
 -#define PLL3_PFD1_FREQ                540000000
 -#define PLL3_PFD2_FREQ                508200000
 -#define PLL3_PFD3_FREQ                454700000
 -#define PLL3_80M              80000000
 -#define PLL3_60M              60000000
++#define MXC_CCM_CCGR6_VDOAXICLK_OFFSET                        12
++#define MXC_CCM_CCGR6_VDOAXICLK_MASK                  (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
 +#endif
 +
- #define BM_ANADIG_PLL_SYS_LOCK 0x80000000
- #define BP_ANADIG_PLL_SYS_RSVD0      20
- #define BM_ANADIG_PLL_SYS_RSVD0 0x7FF00000
- #define BF_ANADIG_PLL_SYS_RSVD0(v)  \
-       (((v) << 20) & BM_ANADIG_PLL_SYS_RSVD0)
- #define BM_ANADIG_PLL_SYS_PLL_SEL 0x00080000
- #define BM_ANADIG_PLL_SYS_LVDS_24MHZ_SEL 0x00040000
- #define BM_ANADIG_PLL_SYS_LVDS_SEL 0x00020000
- #define BM_ANADIG_PLL_SYS_BYPASS 0x00010000
- #define BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC      14
- #define BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_PLL_SYS_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC)
- #define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_PLL_SYS_ENABLE 0x00002000
- #define BM_ANADIG_PLL_SYS_POWERDOWN 0x00001000
- #define BM_ANADIG_PLL_SYS_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_PLL_SYS_DOUBLE_CP 0x00000400
- #define BM_ANADIG_PLL_SYS_HALF_CP 0x00000200
- #define BM_ANADIG_PLL_SYS_DOUBLE_LF 0x00000100
- #define BM_ANADIG_PLL_SYS_HALF_LF 0x00000080
- #define BP_ANADIG_PLL_SYS_DIV_SELECT      0
- #define BM_ANADIG_PLL_SYS_DIV_SELECT 0x0000007F
- #define BF_ANADIG_PLL_SYS_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_SYS_DIV_SELECT)
- #define BM_ANADIG_USB1_PLL_480_CTRL_LOCK 0x80000000
- #define BP_ANADIG_USB1_PLL_480_CTRL_RSVD1      17
- #define BM_ANADIG_USB1_PLL_480_CTRL_RSVD1 0x7FFE0000
- #define BF_ANADIG_USB1_PLL_480_CTRL_RSVD1(v)  \
-       (((v) << 17) & BM_ANADIG_USB1_PLL_480_CTRL_RSVD1)
- #define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS 0x00010000
- #define BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC      14
- #define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC)
- #define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_USB1_PLL_480_CTRL_ENABLE 0x00002000
- #define BM_ANADIG_USB1_PLL_480_CTRL_POWER 0x00001000
- #define BM_ANADIG_USB1_PLL_480_CTRL_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_CP 0x00000400
- #define BM_ANADIG_USB1_PLL_480_CTRL_HALF_CP 0x00000200
- #define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_LF 0x00000100
- #define BM_ANADIG_USB1_PLL_480_CTRL_HALF_LF 0x00000080
- #define BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS 0x00000040
- #define BM_ANADIG_USB1_PLL_480_CTRL_RSVD0 0x00000020
- #define BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0      2
- #define BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0 0x0000001C
- #define BF_ANADIG_USB1_PLL_480_CTRL_CONTROL0(v)  \
-       (((v) << 2) & BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0)
- #define BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT      0
- #define BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT 0x00000003
- #define BF_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT)
- #define BM_ANADIG_PLL_528_LOCK 0x80000000
- #define BP_ANADIG_PLL_528_RSVD1      19
- #define BM_ANADIG_PLL_528_RSVD1 0x7FF80000
- #define BF_ANADIG_PLL_528_RSVD1(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_528_RSVD1)
- #define BM_ANADIG_PLL_528_PFD_OFFSET_EN 0x00040000
- #define BM_ANADIG_PLL_528_DITHER_ENABLE 0x00020000
- #define BM_ANADIG_PLL_528_BYPASS 0x00010000
- #define BP_ANADIG_PLL_528_BYPASS_CLK_SRC      14
- #define BM_ANADIG_PLL_528_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_PLL_528_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_528_BYPASS_CLK_SRC)
- #define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_PLL_528_ENABLE 0x00002000
- #define BM_ANADIG_PLL_528_POWERDOWN 0x00001000
- #define BM_ANADIG_PLL_528_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_PLL_528_DOUBLE_CP 0x00000400
- #define BM_ANADIG_PLL_528_HALF_CP 0x00000200
- #define BM_ANADIG_PLL_528_DOUBLE_LF 0x00000100
- #define BM_ANADIG_PLL_528_HALF_LF 0x00000080
- #define BP_ANADIG_PLL_528_RSVD0      1
- #define BM_ANADIG_PLL_528_RSVD0 0x0000007E
- #define BF_ANADIG_PLL_528_RSVD0(v)  \
-       (((v) << 1) & BM_ANADIG_PLL_528_RSVD0)
- #define BM_ANADIG_PLL_528_DIV_SELECT 0x00000001
- #define BP_ANADIG_PLL_528_SS_STOP      16
- #define BM_ANADIG_PLL_528_SS_STOP 0xFFFF0000
- #define BF_ANADIG_PLL_528_SS_STOP(v) \
-       (((v) << 16) & BM_ANADIG_PLL_528_SS_STOP)
- #define BM_ANADIG_PLL_528_SS_ENABLE 0x00008000
- #define BP_ANADIG_PLL_528_SS_STEP      0
- #define BM_ANADIG_PLL_528_SS_STEP 0x00007FFF
- #define BF_ANADIG_PLL_528_SS_STEP(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_SS_STEP)
- #define BP_ANADIG_PLL_528_NUM_RSVD0      30
- #define BM_ANADIG_PLL_528_NUM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_528_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_528_NUM_RSVD0)
- #define BP_ANADIG_PLL_528_NUM_A      0
- #define BM_ANADIG_PLL_528_NUM_A 0x3FFFFFFF
- #define BF_ANADIG_PLL_528_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_NUM_A)
- #define BP_ANADIG_PLL_528_DENOM_RSVD0      30
- #define BM_ANADIG_PLL_528_DENOM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_528_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_528_DENOM_RSVD0)
- #define BP_ANADIG_PLL_528_DENOM_B      0
- #define BM_ANADIG_PLL_528_DENOM_B 0x3FFFFFFF
- #define BF_ANADIG_PLL_528_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_DENOM_B)
- #define BM_ANADIG_PLL_AUDIO_LOCK 0x80000000
- #define BP_ANADIG_PLL_AUDIO_RSVD0      22
- #define BM_ANADIG_PLL_AUDIO_RSVD0 0x7FC00000
- #define BF_ANADIG_PLL_AUDIO_RSVD0(v)  \
-       (((v) << 22) & BM_ANADIG_PLL_AUDIO_RSVD0)
- #define BM_ANADIG_PLL_AUDIO_SSC_EN 0x00200000
- #define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT      19
- #define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT 0x00180000
- #define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
- #define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN 0x00040000
- #define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE 0x00020000
- #define BM_ANADIG_PLL_AUDIO_BYPASS 0x00010000
- #define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC      14
- #define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
- #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_PLL_AUDIO_ENABLE 0x00002000
- #define BM_ANADIG_PLL_AUDIO_POWERDOWN 0x00001000
- #define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_PLL_AUDIO_DOUBLE_CP 0x00000400
- #define BM_ANADIG_PLL_AUDIO_HALF_CP 0x00000200
- #define BM_ANADIG_PLL_AUDIO_DOUBLE_LF 0x00000100
- #define BM_ANADIG_PLL_AUDIO_HALF_LF 0x00000080
- #define BP_ANADIG_PLL_AUDIO_DIV_SELECT      0
- #define BM_ANADIG_PLL_AUDIO_DIV_SELECT 0x0000007F
- #define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_DIV_SELECT)
- #define BP_ANADIG_PLL_AUDIO_NUM_RSVD0      30
- #define BM_ANADIG_PLL_AUDIO_NUM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_AUDIO_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_AUDIO_NUM_RSVD0)
- #define BP_ANADIG_PLL_AUDIO_NUM_A      0
- #define BM_ANADIG_PLL_AUDIO_NUM_A 0x3FFFFFFF
- #define BF_ANADIG_PLL_AUDIO_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_NUM_A)
- #define BP_ANADIG_PLL_AUDIO_DENOM_RSVD0      30
- #define BM_ANADIG_PLL_AUDIO_DENOM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_AUDIO_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_AUDIO_DENOM_RSVD0)
- #define BP_ANADIG_PLL_AUDIO_DENOM_B      0
- #define BM_ANADIG_PLL_AUDIO_DENOM_B 0x3FFFFFFF
- #define BF_ANADIG_PLL_AUDIO_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_DENOM_B)
- #define BM_ANADIG_PLL_VIDEO_LOCK 0x80000000
- #define BP_ANADIG_PLL_VIDEO_RSVD0      22
- #define BM_ANADIG_PLL_VIDEO_RSVD0 0x7FC00000
- #define BF_ANADIG_PLL_VIDEO_RSVD0(v)  \
-       (((v) << 22) & BM_ANADIG_PLL_VIDEO_RSVD0)
- #define BM_ANADIG_PLL_VIDEO_SSC_EN 0x00200000
- #define BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT      19
- #define BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT 0x00180000
- #define BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
- #define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN 0x00040000
- #define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE 0x00020000
- #define BM_ANADIG_PLL_VIDEO_BYPASS 0x00010000
- #define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC      14
- #define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
- #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_PLL_VIDEO_ENABLE 0x00002000
- #define BM_ANADIG_PLL_VIDEO_POWERDOWN 0x00001000
- #define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_PLL_VIDEO_DOUBLE_CP 0x00000400
- #define BM_ANADIG_PLL_VIDEO_HALF_CP 0x00000200
- #define BM_ANADIG_PLL_VIDEO_DOUBLE_LF 0x00000100
- #define BM_ANADIG_PLL_VIDEO_HALF_LF 0x00000080
- #define BP_ANADIG_PLL_VIDEO_DIV_SELECT      0
- #define BM_ANADIG_PLL_VIDEO_DIV_SELECT 0x0000007F
- #define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_DIV_SELECT)
- #define BP_ANADIG_PLL_VIDEO_NUM_RSVD0      30
- #define BM_ANADIG_PLL_VIDEO_NUM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_VIDEO_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_VIDEO_NUM_RSVD0)
- #define BP_ANADIG_PLL_VIDEO_NUM_A      0
- #define BM_ANADIG_PLL_VIDEO_NUM_A 0x3FFFFFFF
- #define BF_ANADIG_PLL_VIDEO_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_NUM_A)
- #define BP_ANADIG_PLL_VIDEO_DENOM_RSVD0      30
- #define BM_ANADIG_PLL_VIDEO_DENOM_RSVD0 0xC0000000
- #define BF_ANADIG_PLL_VIDEO_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_VIDEO_DENOM_RSVD0)
- #define BP_ANADIG_PLL_VIDEO_DENOM_B      0
- #define BM_ANADIG_PLL_VIDEO_DENOM_B 0x3FFFFFFF
- #define BF_ANADIG_PLL_VIDEO_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_DENOM_B)
- #define BM_ANADIG_PLL_ENET_LOCK 0x80000000
- #define BP_ANADIG_PLL_ENET_RSVD1      21
- #define BM_ANADIG_PLL_ENET_RSVD1 0x7FE00000
- #define BF_ANADIG_PLL_ENET_RSVD1(v)  \
-       (((v) << 21) & BM_ANADIG_PLL_ENET_RSVD1)
- #define BM_ANADIG_PLL_ENET_REF_25M_ENABLE 0x00200000
- #define BM_ANADIG_PLL_ENET_ENABLE_SATA 0x00100000
- #define BM_ANADIG_PLL_ENET_ENABLE_PCIE 0x00080000
- #define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN 0x00040000
- #define BM_ANADIG_PLL_ENET_DITHER_ENABLE 0x00020000
- #define BM_ANADIG_PLL_ENET_BYPASS 0x00010000
- #define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC      14
- #define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC 0x0000C000
- #define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
- #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M  0x0
- #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1 0x1
- #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2 0x2
- #define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR      0x3
- #define BM_ANADIG_PLL_ENET_ENABLE 0x00002000
- #define BM_ANADIG_PLL_ENET_POWERDOWN 0x00001000
- #define BM_ANADIG_PLL_ENET_HOLD_RING_OFF 0x00000800
- #define BM_ANADIG_PLL_ENET_DOUBLE_CP 0x00000400
- #define BM_ANADIG_PLL_ENET_HALF_CP 0x00000200
- #define BM_ANADIG_PLL_ENET_DOUBLE_LF 0x00000100
- #define BM_ANADIG_PLL_ENET_HALF_LF 0x00000080
- #define BP_ANADIG_PLL_ENET_RSVD0      2
- #define BM_ANADIG_PLL_ENET_RSVD0 0x0000007C
- #define BF_ANADIG_PLL_ENET_RSVD0(v)  \
-       (((v) << 2) & BM_ANADIG_PLL_ENET_RSVD0)
- #define BP_ANADIG_PLL_ENET_DIV_SELECT      0
- #define BM_ANADIG_PLL_ENET_DIV_SELECT 0x00000003
- #define BF_ANADIG_PLL_ENET_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_ENET_DIV_SELECT)
- #define BM_ANADIG_PFD_480_PFD3_CLKGATE 0x80000000
- #define BM_ANADIG_PFD_480_PFD3_STABLE 0x40000000
- #define BP_ANADIG_PFD_480_PFD3_FRAC      24
- #define BM_ANADIG_PFD_480_PFD3_FRAC 0x3F000000
- #define BF_ANADIG_PFD_480_PFD3_FRAC(v)  \
-       (((v) << 24) & BM_ANADIG_PFD_480_PFD3_FRAC)
- #define BM_ANADIG_PFD_480_PFD2_CLKGATE 0x00800000
- #define BM_ANADIG_PFD_480_PFD2_STABLE 0x00400000
- #define BP_ANADIG_PFD_480_PFD2_FRAC      16
- #define BM_ANADIG_PFD_480_PFD2_FRAC 0x003F0000
- #define BF_ANADIG_PFD_480_PFD2_FRAC(v)  \
-       (((v) << 16) & BM_ANADIG_PFD_480_PFD2_FRAC)
- #define BM_ANADIG_PFD_480_PFD1_CLKGATE 0x00008000
- #define BM_ANADIG_PFD_480_PFD1_STABLE 0x00004000
- #define BP_ANADIG_PFD_480_PFD1_FRAC      8
- #define BM_ANADIG_PFD_480_PFD1_FRAC 0x00003F00
- #define BF_ANADIG_PFD_480_PFD1_FRAC(v)  \
-       (((v) << 8) & BM_ANADIG_PFD_480_PFD1_FRAC)
- #define BM_ANADIG_PFD_480_PFD0_CLKGATE 0x00000080
- #define BM_ANADIG_PFD_480_PFD0_STABLE 0x00000040
- #define BP_ANADIG_PFD_480_PFD0_FRAC      0
- #define BM_ANADIG_PFD_480_PFD0_FRAC 0x0000003F
- #define BF_ANADIG_PFD_480_PFD0_FRAC(v)  \
-       (((v) << 0) & BM_ANADIG_PFD_480_PFD0_FRAC)
- #define BM_ANADIG_PFD_528_PFD3_CLKGATE 0x80000000
- #define BM_ANADIG_PFD_528_PFD3_STABLE 0x40000000
- #define BP_ANADIG_PFD_528_PFD3_FRAC      24
- #define BM_ANADIG_PFD_528_PFD3_FRAC 0x3F000000
- #define BF_ANADIG_PFD_528_PFD3_FRAC(v)  \
-       (((v) << 24) & BM_ANADIG_PFD_528_PFD3_FRAC)
- #define BM_ANADIG_PFD_528_PFD2_CLKGATE 0x00800000
- #define BM_ANADIG_PFD_528_PFD2_STABLE 0x00400000
- #define BP_ANADIG_PFD_528_PFD2_FRAC      16
- #define BM_ANADIG_PFD_528_PFD2_FRAC 0x003F0000
- #define BF_ANADIG_PFD_528_PFD2_FRAC(v)  \
-       (((v) << 16) & BM_ANADIG_PFD_528_PFD2_FRAC)
- #define BM_ANADIG_PFD_528_PFD1_CLKGATE 0x00008000
- #define BM_ANADIG_PFD_528_PFD1_STABLE 0x00004000
- #define BP_ANADIG_PFD_528_PFD1_FRAC      8
- #define BM_ANADIG_PFD_528_PFD1_FRAC 0x00003F00
- #define BF_ANADIG_PFD_528_PFD1_FRAC(v)  \
-       (((v) << 8) & BM_ANADIG_PFD_528_PFD1_FRAC)
- #define BM_ANADIG_PFD_528_PFD0_CLKGATE 0x00000080
- #define BM_ANADIG_PFD_528_PFD0_STABLE 0x00000040
- #define BP_ANADIG_PFD_528_PFD0_FRAC      0
- #define BM_ANADIG_PFD_528_PFD0_FRAC 0x0000003F
- #define BF_ANADIG_PFD_528_PFD0_FRAC(v)  \
-       (((v) << 0) & BM_ANADIG_PFD_528_PFD0_FRAC)
++#define BM_ANADIG_USB_PLL_480_CTRL_LOCK               (1 << 31)
++#define BM_ANADIG_USB_PLL_480_CTRL_BYPASS             (1 << 16)
++#define BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC     14
++#define BM_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC     (0x3 << BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC)
++#define BF_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC(v)         \
++      (((v) << BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC) & \
++              BM_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC)
++#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M    0x0
++#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1   0x1
++#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2   0x2
++#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__XOR                0x3
++#define BM_ANADIG_USB_PLL_480_CTRL_ENABLE             (1 << 13)
++#define BM_ANADIG_USB_PLL_480_CTRL_POWER              (1 << 12)
++#define BM_ANADIG_USB_PLL_480_CTRL_HOLD_RING_OFF      (1 << 11)
++#define BM_ANADIG_USB_PLL_480_CTRL_DOUBLE_CP          (1 << 10)
++#define BM_ANADIG_USB_PLL_480_CTRL_HALF_CP            (1 << 9)
++#define BM_ANADIG_USB_PLL_480_CTRL_DOUBLE_LF          (1 << 8)
++#define BM_ANADIG_USB_PLL_480_CTRL_HALF_LF            (1 << 7)
++#define BM_ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS                (1 << 6)
++#define BP_ANADIG_USB_PLL_480_CTRL_CONTROL0           2
++#define BM_ANADIG_USB_PLL_480_CTRL_CONTROL0           (0x7 << BP_ANADIG_USB_PLL_480_CTRL_CONTROL0)
++#define BF_ANADIG_USB_PLL_480_CTRL_CONTROL0(v)                 \
++      (((v) << BP_ANADIG_USB_PLL_480_CTRL_CONTROL0) & \
++              BM_ANADIG_USB_PLL_480_CTRL_CONTROL0)
++#define BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT         0
++#define BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT         (0x3 << BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT)
++#define BF_ANADIG_USB_PLL_480_CTRL_DIV_SELECT(v)         \
++      (((v) << BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT) & \
++              BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT)
++
++#define BM_ANADIG_PLL_528_LOCK                                (1 << 31)
++#define BM_ANADIG_PLL_528_PLL_SEL                     (1 << 19)
++#define BM_ANADIG_PLL_528_LVDS_24MHZ_SEL              (1 << 18)
++#define BM_ANADIG_PLL_528_LVDS_SEL                    (1 << 17)
++#define BM_ANADIG_PLL_528_BYPASS                      (1 << 16)
++#define BP_ANADIG_PLL_528_BYPASS_CLK_SRC              14
++#define BM_ANADIG_PLL_528_BYPASS_CLK_SRC              (0x3 << BP_ANADIG_PLL_528_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_528_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_528_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_528_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__OSC_24M     0x0
++#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_1    0x1
++#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_2    0x2
++#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__XOR         0x3
++#define BM_ANADIG_PLL_528_ENABLE                      (1 << 13)
++#define BM_ANADIG_PLL_528_POWERDOWN                   (1 << 12)
++#define BM_ANADIG_PLL_528_HOLD_RING_OFF                       (1 << 11)
++#define BM_ANADIG_PLL_528_DOUBLE_CP                   (1 << 10)
++#define BM_ANADIG_PLL_528_HALF_CP                     (1 << 9)
++#define BM_ANADIG_PLL_528_DOUBLE_LF                   (1 << 8)
++#define BM_ANADIG_PLL_528_HALF_LF                     (1 << 7)
++#define BP_ANADIG_PLL_528_DIV_SELECT                  0
++#define BM_ANADIG_PLL_528_DIV_SELECT                  (0x7F << BP_ANADIG_PLL_528_DIV_SELECT)
++#define BF_ANADIG_PLL_528_DIV_SELECT(v)                \
++      (((v) << BP_ANADIG_PLL_528_DIV_SELECT) & \
++              BM_ANADIG_PLL_528_DIV_SELECT)
++
++#define BP_ANADIG_PLL_528_SS_STOP                     16
++#define BM_ANADIG_PLL_528_SS_STOP                     (0xFFFF << BP_ANADIG_PLL_528_SS_STOP)
++#define BF_ANADIG_PLL_528_SS_STOP(v)        \
++      (((v) << BP_ANADIG_PLL_528_SS_STOP) & \
++              BM_ANADIG_PLL_528_SS_STOP)
++#define BM_ANADIG_PLL_528_SS_ENABLE                   (1 << 15)
++#define BP_ANADIG_PLL_528_SS_STEP                     0
++#define BM_ANADIG_PLL_528_SS_STEP                     (0x7FFF << BP_ANADIG_PLL_528_SS_STEP)
++#define BF_ANADIG_PLL_528_SS_STEP(v)        \
++      (((v) << BP_ANADIG_PLL_528_SS_STEP) & \
++              BM_ANADIG_PLL_528_SS_STEP)
++
++#define BP_ANADIG_PLL_528_NUM_A                               0
++#define BM_ANADIG_PLL_528_NUM_A                               (0x3FFFFFFF << BP_ANADIG_PLL_528_NUM_A)
++#define BF_ANADIG_PLL_528_NUM_A(v)        \
++      (((v) << BP_ANADIG_PLL_528_NUM_A) & \
++              BM_ANADIG_PLL_528_NUM_A)
++
++#define BP_ANADIG_PLL_528_DENOM_B                     0
++#define BM_ANADIG_PLL_528_DENOM_B                     (0x3FFFFFFF << BP_ANADIG_PLL_528_DENOM_B)
++#define BF_ANADIG_PLL_528_DENOM_B(v)        \
++      (((v) << BP_ANADIG_PLL_528_DENOM_B) & \
++              BM_ANADIG_PLL_528_DENOM_B)
++
++#define BM_ANADIG_PLL_AUDIO_LOCK                      (1 << 31)
++#define BM_ANADIG_PLL_AUDIO_SSC_EN                    (1 << 21)
++#define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT           19
++#define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT           (0x3 << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
++#define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)                \
++      (((v) << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) & \
++              BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
++#define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN             (1 << 18)
++#define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE             (1 << 17)
++#define BM_ANADIG_PLL_AUDIO_BYPASS                    (1 << 16)
++#define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC            14
++#define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC            (0x3 << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M   0x0
++#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1  0x1
++#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2  0x2
++#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR               0x3
++#define BM_ANADIG_PLL_AUDIO_ENABLE                    (1 << 13)
++#define BM_ANADIG_PLL_AUDIO_POWERDOWN                 (1 << 12)
++#define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF             (1 << 11)
++#define BM_ANADIG_PLL_AUDIO_DOUBLE_CP                 (1 << 10)
++#define BM_ANADIG_PLL_AUDIO_HALF_CP                   (1 << 9)
++#define BM_ANADIG_PLL_AUDIO_DOUBLE_LF                 (1 << 8)
++#define BM_ANADIG_PLL_AUDIO_HALF_LF                   (1 << 7)
++#define BP_ANADIG_PLL_AUDIO_DIV_SELECT                        0
++#define BM_ANADIG_PLL_AUDIO_DIV_SELECT                        (0x7F << BP_ANADIG_PLL_AUDIO_DIV_SELECT)
++#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_AUDIO_DIV_SELECT) & \
++              BM_ANADIG_PLL_AUDIO_DIV_SELECT)
++
++#define BP_ANADIG_PLL_AUDIO_NUM_A                     0
++#define BM_ANADIG_PLL_AUDIO_NUM_A                     (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_NUM_A)
++#define BF_ANADIG_PLL_AUDIO_NUM_A(v)        \
++      (((v) << BP_ANADIG_PLL_AUDIO_NUM_A) & \
++              BM_ANADIG_PLL_AUDIO_NUM_A)
++
++#define BP_ANADIG_PLL_AUDIO_DENOM_B                   0
++#define BM_ANADIG_PLL_AUDIO_DENOM_B                   (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_DENOM_B)
++#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)                \
++      (((v) << BP_ANADIG_PLL_AUDIO_DENOM_B) & \
++              BM_ANADIG_PLL_AUDIO_DENOM_B)
++
++#define BM_ANADIG_PLL_VIDEO_LOCK                      (1 << 31)
++#define BM_ANADIG_PLL_VIDEO_SSC_EN                    (1 << 21)
++#define BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT           19
++#define BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT           (0x3 << BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
++#define BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(v)                \
++      (((v) << BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT) & \
++              BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
++#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN             (1 << 18)
++#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE             (1 << 17)
++#define BM_ANADIG_PLL_VIDEO_BYPASS                    (1 << 16)
++#define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC            14
++#define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC            (0x3 << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M   0x0
++#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1  0x1
++#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2  0x2
++#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR               0x3
++#define BM_ANADIG_PLL_VIDEO_ENABLE                    (1 << 13)
++#define BM_ANADIG_PLL_VIDEO_POWERDOWN                 (1 << 12)
++#define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF             (1 << 11)
++#define BM_ANADIG_PLL_VIDEO_DOUBLE_CP                 (1 << 10)
++#define BM_ANADIG_PLL_VIDEO_HALF_CP                   (1 << 9)
++#define BM_ANADIG_PLL_VIDEO_DOUBLE_LF                 (1 << 8)
++#define BM_ANADIG_PLL_VIDEO_HALF_LF                   (1 << 7)
++#define BP_ANADIG_PLL_VIDEO_DIV_SELECT                        0
++#define BM_ANADIG_PLL_VIDEO_DIV_SELECT                        (0x7F << BP_ANADIG_PLL_VIDEO_DIV_SELECT)
++#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_DIV_SELECT) & \
++              BM_ANADIG_PLL_VIDEO_DIV_SELECT)
++
++#define BP_ANADIG_PLL_VIDEO_NUM_A                     0
++#define BM_ANADIG_PLL_VIDEO_NUM_A                     (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_NUM_A)
++#define BF_ANADIG_PLL_VIDEO_NUM_A(v)        \
++      (((v) << BP_ANADIG_PLL_VIDEO_NUM_A) & \
++              BM_ANADIG_PLL_VIDEO_NUM_A)
++
++#define BP_ANADIG_PLL_VIDEO_DENOM_B                   0
++#define BM_ANADIG_PLL_VIDEO_DENOM_B                   (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_DENOM_B)
++#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)                \
++      (((v) << BP_ANADIG_PLL_VIDEO_DENOM_B) & \
++              BM_ANADIG_PLL_VIDEO_DENOM_B)
++
++#define BM_ANADIG_PLL_ENET_LOCK                               (1 << 31)
++#define BM_ANADIG_PLL_ENET_REF_25M_ENABLE             (1 << 21)
++#define BM_ANADIG_PLL_ENET_ENABLE_SATA                        (1 << 20)
++#define BM_ANADIG_PLL_ENET_ENABLE_PCIE                        (1 << 19)
++#define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN              (1 << 18)
++#define BM_ANADIG_PLL_ENET_DITHER_ENABLE              (1 << 17)
++#define BM_ANADIG_PLL_ENET_BYPASS                     (1 << 16)
++#define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC             14
++#define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
++#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)        \
++      (((v) << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC) & \
++              BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
++#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M    0x0
++#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1   0x1
++#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2   0x2
++#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR                0x3
++#define BM_ANADIG_PLL_ENET_ENABLE                     (1 << 13)
++#define BM_ANADIG_PLL_ENET_POWERDOWN                  (1 << 12)
++#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF              (1 << 11)
++#define BM_ANADIG_PLL_ENET_DOUBLE_CP                  (1 << 10)
++#define BM_ANADIG_PLL_ENET_HALF_CP                    (1 << 9)
++#define BM_ANADIG_PLL_ENET_DOUBLE_LF                  (1 << 8)
++#define BM_ANADIG_PLL_ENET_HALF_LF                    (1 << 7)
++#define BP_ANADIG_PLL_ENET_DIV_SELECT                 0
++#define BM_ANADIG_PLL_ENET_DIV_SELECT                 (0x3 << BP_ANADIG_PLL_ENET_DIV_SELECT)
++#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)        \
++      (((v) << BP_ANADIG_PLL_ENET_DIV_SELECT) & \
++              BM_ANADIG_PLL_ENET_DIV_SELECT)
++
++#define BM_ANADIG_PFD_480_PFD3_CLKGATE                        (1 << 31)
++#define BM_ANADIG_PFD_480_PFD3_STABLE                 (1 << 30)
++#define BP_ANADIG_PFD_480_PFD3_FRAC                   24
++#define BM_ANADIG_PFD_480_PFD3_FRAC                   (0x3F << BP_ANADIG_PFD_480_PFD3_FRAC)
++#define BF_ANADIG_PFD_480_PFD3_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_480_PFD3_FRAC) & \
++              BM_ANADIG_PFD_480_PFD3_FRAC)
++#define BM_ANADIG_PFD_480_PFD2_CLKGATE                        (1 << 23)
++#define BM_ANADIG_PFD_480_PFD2_STABLE                 (1 << 22)
++#define BP_ANADIG_PFD_480_PFD2_FRAC                   16
++#define BM_ANADIG_PFD_480_PFD2_FRAC                   (0x3F << BP_ANADIG_PFD_480_PFD2_FRAC)
++#define BF_ANADIG_PFD_480_PFD2_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_480_PFD2_FRAC) & \
++              BM_ANADIG_PFD_480_PFD2_FRAC)
++#define BM_ANADIG_PFD_480_PFD1_CLKGATE                        (1 << 15)
++#define BM_ANADIG_PFD_480_PFD1_STABLE                 (1 << 14)
++#define BP_ANADIG_PFD_480_PFD1_FRAC                   8
++#define BM_ANADIG_PFD_480_PFD1_FRAC                   (0x3F << BP_ANADIG_PFD_480_PFD1_FRAC)
++#define BF_ANADIG_PFD_480_PFD1_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_480_PFD1_FRAC) & \
++              BM_ANADIG_PFD_480_PFD1_FRAC)
++#define BM_ANADIG_PFD_480_PFD0_CLKGATE                        (1 << 7)
++#define BM_ANADIG_PFD_480_PFD0_STABLE                 (1 << 6)
++#define BP_ANADIG_PFD_480_PFD0_FRAC                   0
++#define BM_ANADIG_PFD_480_PFD0_FRAC                   (0x3F << BP_ANADIG_PFD_480_PFD0_FRAC)
++#define BF_ANADIG_PFD_480_PFD0_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_480_PFD0_FRAC) & \
++              BM_ANADIG_PFD_480_PFD0_FRAC)
++
++#define BM_ANADIG_PFD_528_PFD3_CLKGATE                        (1 << 31)
++#define BM_ANADIG_PFD_528_PFD3_STABLE                 (1 << 30)
++#define BP_ANADIG_PFD_528_PFD3_FRAC                   24
++#define BM_ANADIG_PFD_528_PFD3_FRAC                   (0x3F << BP_ANADIG_PFD_528_PFD3_FRAC)
++#define BF_ANADIG_PFD_528_PFD3_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_528_PFD3_FRAC) & \
++              BM_ANADIG_PFD_528_PFD3_FRAC)
++#define BM_ANADIG_PFD_528_PFD2_CLKGATE                        (1 << 23)
++#define BM_ANADIG_PFD_528_PFD2_STABLE                 (1 << 22)
++#define BP_ANADIG_PFD_528_PFD2_FRAC                   16
++#define BM_ANADIG_PFD_528_PFD2_FRAC                   (0x3F << BP_ANADIG_PFD_528_PFD2_FRAC)
++#define BF_ANADIG_PFD_528_PFD2_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_528_PFD2_FRAC) & \
++              BM_ANADIG_PFD_528_PFD2_FRAC)
++#define BM_ANADIG_PFD_528_PFD1_CLKGATE                        (1 << 15)
++#define BM_ANADIG_PFD_528_PFD1_STABLE                 (1 << 14)
++#define BP_ANADIG_PFD_528_PFD1_FRAC                   8
++#define BM_ANADIG_PFD_528_PFD1_FRAC                   (0x3F << BP_ANADIG_PFD_528_PFD1_FRAC)
++#define BF_ANADIG_PFD_528_PFD1_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_528_PFD1_FRAC) & \
++              BM_ANADIG_PFD_528_PFD1_FRAC)
++#define BM_ANADIG_PFD_528_PFD0_CLKGATE                        (1 << 7)
++#define BM_ANADIG_PFD_528_PFD0_STABLE                 (1 << 6)
++#define BP_ANADIG_PFD_528_PFD0_FRAC                   0
++#define BM_ANADIG_PFD_528_PFD0_FRAC                   (0x3F << BP_ANADIG_PFD_528_PFD0_FRAC)
++#define BF_ANADIG_PFD_528_PFD0_FRAC(v)                \
++      (((v) << BP_ANADIG_PFD_528_PFD0_FRAC) & \
++              BM_ANADIG_PFD_528_PFD0_FRAC)
  
  #endif /*__ARCH_ARM_MACH_MX6_CCM_REGS_H__ */
index c968600b770f397972722e655221a0f834d49d6c,669463526a4efd67ff4428b4a2565e33e13c0112..7368572cbc9f2b8116a2f9d0398b6d63e48dc26b
@@@ -7,44 -7,31 +7,46 @@@
  #ifndef __ASM_ARCH_MX6_IMX_REGS_H__
  #define __ASM_ARCH_MX6_IMX_REGS_H__
  
+ #include <asm/imx-common/regs-common.h>
  #define ARCH_MXC
  
- #define CONFIG_SYS_CACHELINE_SIZE     32
++#define CONFIG_SYS_CACHELINE_SIZE       64
 +
- #define ROMCP_ARB_BASE_ADDR             0x00000000
- #define ROMCP_ARB_END_ADDR              0x000FFFFF
+ #define ROMCP_ARB_BASE_ADDR           0x00000000
+ #define ROMCP_ARB_END_ADDR            0x000FFFFF
  
  #ifdef CONFIG_MX6SL
- #define GPU_2D_ARB_BASE_ADDR            0x02200000
- #define GPU_2D_ARB_END_ADDR             0x02203FFF
- #define OPENVG_ARB_BASE_ADDR            0x02204000
- #define OPENVG_ARB_END_ADDR             0x02207FFF
- #elif CONFIG_MX6SX
- #define CAAM_ARB_BASE_ADDR              0x00100000
- #define CAAM_ARB_END_ADDR               0x00107FFF
- #define GPU_ARB_BASE_ADDR               0x01800000
- #define GPU_ARB_END_ADDR                0x01803FFF
- #define APBH_DMA_ARB_BASE_ADDR          0x01804000
- #define APBH_DMA_ARB_END_ADDR           0x0180BFFF
- #define M4_BOOTROM_BASE_ADDR                  0x007F8000
+ #define GPU_2D_ARB_BASE_ADDR          0x02200000
+ #define GPU_2D_ARB_END_ADDR           0x02203FFF
+ #define OPENVG_ARB_BASE_ADDR          0x02204000
+ #define OPENVG_ARB_END_ADDR           0x02207FFF
++#elif defined(CONFIG_MX6SX)
++#define CAAM_ARB_BASE_ADDR            0x00100000
++#define CAAM_ARB_END_ADDR             0x00107FFF
++#define GPU_ARB_BASE_ADDR             0x01800000
++#define GPU_ARB_END_ADDR              0x01803FFF
++#define APBH_DMA_ARB_BASE_ADDR                0x01804000
++#define APBH_DMA_ARB_END_ADDR         0x0180BFFF
++#define M4_BOOTROM_BASE_ADDR          0x007F8000
 +
 +#define MXS_APBH_BASE                 APBH_DMA_ARB_BASE_ADDR
 +#define MXS_GPMI_BASE                 (APBH_DMA_ARB_BASE_ADDR + 0x02000)
 +#define MXS_BCH_BASE                  (APBH_DMA_ARB_BASE_ADDR + 0x04000)
 +
  #else
- #define CAAM_ARB_BASE_ADDR              0x00100000
- #define CAAM_ARB_END_ADDR               0x00103FFF
- #define APBH_DMA_ARB_BASE_ADDR          0x00110000
- #define APBH_DMA_ARB_END_ADDR           0x00117FFF
- #define HDMI_ARB_BASE_ADDR              0x00120000
- #define HDMI_ARB_END_ADDR               0x00128FFF
- #define GPU_3D_ARB_BASE_ADDR            0x00130000
- #define GPU_3D_ARB_END_ADDR             0x00133FFF
- #define GPU_2D_ARB_BASE_ADDR            0x00134000
- #define GPU_2D_ARB_END_ADDR             0x00137FFF
- #define DTCP_ARB_BASE_ADDR              0x00138000
- #define DTCP_ARB_END_ADDR               0x0013BFFF
+ #define CAAM_ARB_BASE_ADDR            0x00100000
+ #define CAAM_ARB_END_ADDR             0x00103FFF
+ #define APBH_DMA_ARB_BASE_ADDR                0x00110000
+ #define APBH_DMA_ARB_END_ADDR         0x00117FFF
+ #define HDMI_ARB_BASE_ADDR            0x00120000
+ #define HDMI_ARB_END_ADDR             0x00128FFF
+ #define GPU_3D_ARB_BASE_ADDR          0x00130000
+ #define GPU_3D_ARB_END_ADDR           0x00133FFF
+ #define GPU_2D_ARB_BASE_ADDR          0x00134000
+ #define GPU_2D_ARB_END_ADDR           0x00137FFF
+ #define DTCP_ARB_BASE_ADDR            0x00138000
+ #define DTCP_ARB_END_ADDR             0x0013BFFF
  #endif        /* CONFIG_MX6SL */
  
  #define MXS_APBH_BASE                 APBH_DMA_ARB_BASE_ADDR
  #define MXS_BCH_BASE                  (APBH_DMA_ARB_BASE_ADDR + 0x04000)
  
  /* GPV - PL301 configuration ports */
 -#ifdef CONFIG_MX6SL
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
- #define GPV2_BASE_ADDR                  0x00D00000
+ #define GPV2_BASE_ADDR                        0x00D00000
  #else
  #define GPV2_BASE_ADDR                        0x00200000
  #endif
  
- #define PCIE_ARB_BASE_ADDR              0x08000000
- #define PCIE_ARB_END_ADDR               0x08FFFFFF
 +#ifdef CONFIG_MX6SX
 +#define GPV3_BASE_ADDR                        0x00E00000
 +#define GPV4_BASE_ADDR                        0x00F00000
 +#define GPV5_BASE_ADDR                        0x01000000
 +#define GPV6_BASE_ADDR                        0x01100000
++#define PCIE_ARB_BASE_ADDR            0x08000000
++#define PCIE_ARB_END_ADDR             0x08FFFFFF
 +
 +#else
  #define GPV3_BASE_ADDR                        0x00300000
  #define GPV4_BASE_ADDR                        0x00800000
- #define PCIE_ARB_BASE_ADDR              0x01000000
- #define PCIE_ARB_END_ADDR               0x01FFFFFF
++#define PCIE_ARB_BASE_ADDR            0x01000000
++#define PCIE_ARB_END_ADDR             0x01FFFFFF
 +#endif
 +
  #define IRAM_BASE_ADDR                        0x00900000
- #define SCU_BASE_ADDR                   0x00A00000
- #define IC_INTERFACES_BASE_ADDR         0x00A00100
- #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
- #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
- #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+ #define SCU_BASE_ADDR                 0x00A00000
+ #define IC_INTERFACES_BASE_ADDR               0x00A00100
+ #define GLOBAL_TIMER_BASE_ADDR                0x00A00200
+ #define PRIVATE_TIMERS_WD_BASE_ADDR   0x00A00600
+ #define IC_DISTRIBUTOR_BASE_ADDR      0x00A01000
 +#define L2_PL310_BASE                 0x00A02000
- #define GPV0_BASE_ADDR                  0x00B00000
- #define GPV1_BASE_ADDR                  0x00C00000
+ #define GPV0_BASE_ADDR                        0x00B00000
+ #define GPV1_BASE_ADDR                        0x00C00000
 -#define PCIE_ARB_BASE_ADDR            0x01000000
 -#define PCIE_ARB_END_ADDR             0x01FFFFFF
  
- #define AIPS1_ARB_BASE_ADDR             0x02000000
- #define AIPS1_ARB_END_ADDR              0x020FFFFF
- #define AIPS2_ARB_BASE_ADDR             0x02100000
- #define AIPS2_ARB_END_ADDR              0x021FFFFF
+ #define AIPS1_ARB_BASE_ADDR           0x02000000
+ #define AIPS1_ARB_END_ADDR            0x020FFFFF
+ #define AIPS2_ARB_BASE_ADDR           0x02100000
+ #define AIPS2_ARB_END_ADDR            0x021FFFFF
 +#ifdef CONFIG_MX6SX
 +#define AIPS3_BASE_ADDR                       0x02200000
 +#define AIPS3_END_ADDR                        0x022FFFFF
- #define WEIM_ARB_BASE_ADDR              0x50000000
- #define WEIM_ARB_END_ADDR               0x57FFFFFF
- #define QSPI0_AMBA_BASE                0x60000000
- #define QSPI0_AMBA_END                 0x6FFFFFFF
- #define QSPI1_AMBA_BASE                0x70000000
- #define QSPI1_AMBA_END                 0x7FFFFFFF
++#define WEIM_ARB_BASE_ADDR            0x50000000
++#define WEIM_ARB_END_ADDR             0x57FFFFFF
++#define QSPI0_AMBA_BASE                       0x60000000
++#define QSPI0_AMBA_END                        0x6FFFFFFF
++#define QSPI1_AMBA_BASE                       0x70000000
++#define QSPI1_AMBA_END                        0x7FFFFFFF
 +#else
- #define SATA_ARB_BASE_ADDR              0x02200000
- #define SATA_ARB_END_ADDR               0x02203FFF
- #define OPENVG_ARB_BASE_ADDR            0x02204000
- #define OPENVG_ARB_END_ADDR             0x02207FFF
- #define HSI_ARB_BASE_ADDR               0x02208000
- #define HSI_ARB_END_ADDR                0x0220BFFF
- #define IPU1_ARB_BASE_ADDR              0x02400000
- #define IPU1_ARB_END_ADDR               0x027FFFFF
- #define IPU2_ARB_BASE_ADDR              0x02800000
- #define IPU2_ARB_END_ADDR               0x02BFFFFF
- #define WEIM_ARB_BASE_ADDR              0x08000000
- #define WEIM_ARB_END_ADDR               0x0FFFFFFF
+ #define SATA_ARB_BASE_ADDR            0x02200000
+ #define SATA_ARB_END_ADDR             0x02203FFF
+ #define OPENVG_ARB_BASE_ADDR          0x02204000
+ #define OPENVG_ARB_END_ADDR           0x02207FFF
+ #define HSI_ARB_BASE_ADDR             0x02208000
+ #define HSI_ARB_END_ADDR              0x0220BFFF
+ #define IPU1_ARB_BASE_ADDR            0x02400000
+ #define IPU1_ARB_END_ADDR             0x027FFFFF
+ #define IPU2_ARB_BASE_ADDR            0x02800000
+ #define IPU2_ARB_END_ADDR             0x02BFFFFF
+ #define WEIM_ARB_BASE_ADDR            0x08000000
+ #define WEIM_ARB_END_ADDR             0x0FFFFFFF
 +#endif
  
 -#ifdef CONFIG_MX6SL
 +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
- #define MMDC0_ARB_BASE_ADDR             0x80000000
- #define MMDC0_ARB_END_ADDR              0xFFFFFFFF
- #define MMDC1_ARB_BASE_ADDR             0xC0000000
- #define MMDC1_ARB_END_ADDR              0xFFFFFFFF
+ #define MMDC0_ARB_BASE_ADDR           0x80000000
+ #define MMDC0_ARB_END_ADDR            0xFFFFFFFF
+ #define MMDC1_ARB_BASE_ADDR           0xC0000000
+ #define MMDC1_ARB_END_ADDR            0xFFFFFFFF
  #else
- #define MMDC0_ARB_BASE_ADDR             0x10000000
- #define MMDC0_ARB_END_ADDR              0x7FFFFFFF
- #define MMDC1_ARB_BASE_ADDR             0x80000000
- #define MMDC1_ARB_END_ADDR              0xFFFFFFFF
+ #define MMDC0_ARB_BASE_ADDR           0x10000000
+ #define MMDC0_ARB_END_ADDR            0x7FFFFFFF
+ #define MMDC1_ARB_BASE_ADDR           0x80000000
+ #define MMDC1_ARB_END_ADDR            0xFFFFFFFF
  #endif
  
 +#ifndef CONFIG_MX6SX
  #define IPU_SOC_BASE_ADDR             IPU1_ARB_BASE_ADDR
  #define IPU_SOC_OFFSET                        0x00200000
 +#endif
  
  /* Defines for Blocks connected via AIPS (SkyBlue) */
- #define ATZ1_BASE_ADDR              AIPS1_ARB_BASE_ADDR
- #define ATZ2_BASE_ADDR              AIPS2_ARB_BASE_ADDR
- #define AIPS1_BASE_ADDR             AIPS1_ON_BASE_ADDR
- #define AIPS2_BASE_ADDR             AIPS2_ON_BASE_ADDR
- #define SPDIF_BASE_ADDR             (ATZ1_BASE_ADDR + 0x04000)
- #define ECSPI1_BASE_ADDR            (ATZ1_BASE_ADDR + 0x08000)
- #define ECSPI2_BASE_ADDR            (ATZ1_BASE_ADDR + 0x0C000)
- #define ECSPI3_BASE_ADDR            (ATZ1_BASE_ADDR + 0x10000)
- #define ECSPI4_BASE_ADDR            (ATZ1_BASE_ADDR + 0x14000)
+ #define ATZ1_BASE_ADDR                    AIPS1_ARB_BASE_ADDR
+ #define ATZ2_BASE_ADDR                    AIPS2_ARB_BASE_ADDR
+ #define AIPS1_BASE_ADDR                   AIPS1_ON_BASE_ADDR
+ #define AIPS2_BASE_ADDR                   AIPS2_ON_BASE_ADDR
+ #define SPDIF_BASE_ADDR                   (ATZ1_BASE_ADDR + 0x04000)
+ #define ECSPI1_BASE_ADDR          (ATZ1_BASE_ADDR + 0x08000)
+ #define ECSPI2_BASE_ADDR          (ATZ1_BASE_ADDR + 0x0C000)
+ #define ECSPI3_BASE_ADDR          (ATZ1_BASE_ADDR + 0x10000)
+ #define ECSPI4_BASE_ADDR          (ATZ1_BASE_ADDR + 0x14000)
  #ifdef CONFIG_MX6SL
- #define UART5_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x18000)
- #define UART1_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x20000)
- #define UART2_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x24000)
- #define SSI1_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x28000)
- #define SSI2_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x2C000)
- #define SSI3_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x30000)
- #define UART3_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x34000)
- #define UART4_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x38000)
+ #define UART5_IPS_BASE_ADDR       (ATZ1_BASE_ADDR + 0x18000)
+ #define UART1_IPS_BASE_ADDR       (ATZ1_BASE_ADDR + 0x20000)
+ #define UART2_IPS_BASE_ADDR       (ATZ1_BASE_ADDR + 0x24000)
+ #define SSI1_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x28000)
+ #define SSI2_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x2C000)
+ #define SSI3_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x30000)
+ #define UART3_IPS_BASE_ADDR       (ATZ1_BASE_ADDR + 0x34000)
+ #define UART4_IPS_BASE_ADDR       (ATZ1_BASE_ADDR + 0x38000)
  #else
- #define ECSPI5_BASE_ADDR            (ATZ1_BASE_ADDR + 0x18000)
 +#ifndef CONFIG_MX6SX
- #define UART1_BASE                  (ATZ1_BASE_ADDR + 0x20000)
- #define ESAI1_BASE_ADDR             (ATZ1_BASE_ADDR + 0x24000)
- #define SSI1_BASE_ADDR              (ATZ1_BASE_ADDR + 0x28000)
- #define SSI2_BASE_ADDR              (ATZ1_BASE_ADDR + 0x2C000)
- #define SSI3_BASE_ADDR              (ATZ1_BASE_ADDR + 0x30000)
- #define ASRC_BASE_ADDR              (ATZ1_BASE_ADDR + 0x34000)
+ #define ECSPI5_BASE_ADDR          (ATZ1_BASE_ADDR + 0x18000)
 +#endif
+ #define UART1_BASE                (ATZ1_BASE_ADDR + 0x20000)
+ #define ESAI1_BASE_ADDR                   (ATZ1_BASE_ADDR + 0x24000)
+ #define SSI1_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x28000)
+ #define SSI2_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x2C000)
+ #define SSI3_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x30000)
+ #define ASRC_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x34000)
  #endif
  
- #define SPBA_BASE_ADDR              (ATZ1_BASE_ADDR + 0x3C000)
- #define VPU_BASE_ADDR               (ATZ1_BASE_ADDR + 0x40000)
 +#ifndef CONFIG_MX6SX
- #define AIPS1_ON_BASE_ADDR          (ATZ1_BASE_ADDR + 0x7C000)
- #define AIPS1_OFF_BASE_ADDR         (ATZ1_BASE_ADDR + 0x80000)
- #define PWM1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x0000)
- #define PWM2_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x4000)
- #define PWM3_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x8000)
- #define PWM4_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0xC000)
- #define CAN1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x10000)
- #define CAN2_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x14000)
- #define GPT1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x18000)
- #define GPIO1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x1C000)
- #define GPIO2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x20000)
- #define GPIO3_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x24000)
- #define GPIO4_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x28000)
- #define GPIO5_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x2C000)
- #define GPIO6_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x30000)
- #define GPIO7_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x34000)
- #define KPP_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x38000)
- #define WDOG1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x3C000)
- #define WDOG2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x40000)
- #define ANATOP_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x48000)
- #define USB_PHY0_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x49000)
- #define USB_PHY1_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x4a000)
- #define CCM_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x44000)
- #define SNVS_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x4C000)
- #define EPIT1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x50000)
- #define EPIT2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x54000)
- #define SRC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x58000)
- #define GPC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x5C000)
- #define IOMUXC_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x60000)
+ #define SPBA_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x3C000)
+ #define VPU_BASE_ADDR             (ATZ1_BASE_ADDR + 0x40000)
 +#endif
+ #define AIPS1_ON_BASE_ADDR        (ATZ1_BASE_ADDR + 0x7C000)
+ #define AIPS1_OFF_BASE_ADDR       (ATZ1_BASE_ADDR + 0x80000)
+ #define PWM1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x0000)
+ #define PWM2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x4000)
+ #define PWM3_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x8000)
+ #define PWM4_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0xC000)
+ #define CAN1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x10000)
+ #define CAN2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x14000)
+ #define GPT1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x18000)
+ #define GPIO1_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x1C000)
+ #define GPIO2_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x20000)
+ #define GPIO3_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x24000)
+ #define GPIO4_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x28000)
+ #define GPIO5_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x2C000)
+ #define GPIO6_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x30000)
+ #define GPIO7_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x34000)
+ #define KPP_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x38000)
+ #define WDOG1_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x3C000)
+ #define WDOG2_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x40000)
+ #define CCM_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x44000)
+ #define ANATOP_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x48000)
+ #define USB_PHY0_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x49000)
+ #define USB_PHY1_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x4a000)
+ #define SNVS_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x4C000)
+ #define EPIT1_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x50000)
+ #define EPIT2_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x54000)
+ #define SRC_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x58000)
+ #define GPC_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x5C000)
+ #define IOMUXC_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x60000)
  #ifdef CONFIG_MX6SL
- #define CSI_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x64000)
- #define SIPIX_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x68000)
+ #define CSI_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x64000)
+ #define SIPIX_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x68000)
  #define SDMA_PORT_HOST_BASE_ADDR    (AIPS1_OFF_BASE_ADDR + 0x6C000)
- #elif CONFIG_MX6SX
++#elif defined(CONFIG_MX6SX)
 +#define CANFD1_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x68000)
 +#define SDMA_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x6C000)
 +#define CANFD2_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x70000)
 +#define SEMAPHORE1_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x74000)
 +#define SEMAPHORE2_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x78000)
 +#define RDC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x7C000)
  #else
- #define DCIC1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x64000)
- #define DCIC2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x68000)
+ #define DCIC1_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x64000)
+ #define DCIC2_BASE_ADDR                   (AIPS1_OFF_BASE_ADDR + 0x68000)
  #define DMA_REQ_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
  #endif
  
- #define AIPS2_ON_BASE_ADDR          (ATZ2_BASE_ADDR + 0x7C000)
- #define AIPS2_OFF_BASE_ADDR         (ATZ2_BASE_ADDR + 0x80000)
- #define CAAM_BASE_ADDR              (ATZ2_BASE_ADDR)
+ #define AIPS2_ON_BASE_ADDR        (ATZ2_BASE_ADDR + 0x7C000)
+ #define AIPS2_OFF_BASE_ADDR       (ATZ2_BASE_ADDR + 0x80000)
+ #define CAAM_BASE_ADDR                    (ATZ2_BASE_ADDR)
  #define ARM_BASE_ADDR             (ATZ2_BASE_ADDR + 0x40000)
- #define USB_PL301_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x0000)
- #define USB_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x4000)
 -#ifdef CONFIG_MX6SL
 -#define USBO2H_PL301_IPS_BASE_ADDR  (AIPS2_OFF_BASE_ADDR + 0x0000)
 -#define USBO2H_USB_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x4000)
 -#else
 -#define USBOH3_PL301_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x0000)
 -#define USBOH3_USB_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x4000)
 -#endif
++#define USB_PL301_BASE_ADDR       (AIPS2_OFF_BASE_ADDR + 0x0000)
++#define USB_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x4000)
  
- #define ENET_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x8000)
+ #define ENET_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x8000)
  #ifdef CONFIG_MX6SL
- #define MSHC_IPS_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0xC000)
+ #define MSHC_IPS_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0xC000)
  #else
- #define MLB_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0xC000)
+ #define MLB_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0xC000)
  #endif
  
- #define USDHC1_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x10000)
- #define USDHC2_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x14000)
- #define USDHC3_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x18000)
- #define USDHC4_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x1C000)
- #define I2C1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x20000)
- #define I2C2_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x24000)
- #define I2C3_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x28000)
- #define ROMCP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x2C000)
- #define MMDC_P0_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x30000)
+ #define USDHC1_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x10000)
+ #define USDHC2_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x14000)
+ #define USDHC3_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x18000)
+ #define USDHC4_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x1C000)
+ #define I2C1_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x20000)
+ #define I2C2_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x24000)
+ #define I2C3_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x28000)
+ #define ROMCP_BASE_ADDR                   (AIPS2_OFF_BASE_ADDR + 0x2C000)
+ #define MMDC_P0_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x30000)
  #ifdef CONFIG_MX6SL
- #define RNGB_IPS_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x34000)
- #elif CONFIG_MX6SX
- #define ENET2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x34000)
+ #define RNGB_IPS_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x34000)
++#elif defined(CONFIG_MX6SX)
++#define ENET2_BASE_ADDR                   (AIPS2_OFF_BASE_ADDR + 0x34000)
  #else
- #define MMDC_P1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x34000)
+ #define MMDC_P1_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x34000)
  #endif
  
- #define WEIM_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x38000)
- #define OCOTP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x3C000)
- #define CSU_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x40000)
+ #define WEIM_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x38000)
+ #define OCOTP_BASE_ADDR                   (AIPS2_OFF_BASE_ADDR + 0x3C000)
+ #define CSU_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x40000)
  #define IP2APB_PERFMON1_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x44000)
  #define IP2APB_PERFMON2_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x48000)
 +#ifdef CONFIG_MX6SX
 +#define DEBUG_MONITOR_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x4C000)
 +#else
  #define IP2APB_PERFMON3_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x4C000)
- #define IP2APB_TZASC1_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x50000)
 +#endif
- #define SAI1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x54000)
+ #define IP2APB_TZASC1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x50000)
 +#ifdef CONFIG_MX6SX
- #define IP2APB_TZASC2_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x54000)
++#define SAI1_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x54000)
 +#else
- #define AUDMUX_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x58000)
- #define AUDMUX_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x58000)
+ #define IP2APB_TZASC2_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x54000)
 +#endif
- #define SAI2_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x5C000)
- #define QSPI0_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x60000)
- #define QSPI1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x64000)
+ #define AUDMUX_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x58000)
 +#ifdef CONFIG_MX6SX
- #define MIPI_CSI2_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x5C000)
- #define MIPI_DSI_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x60000)
- #define VDOA_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x64000)
++#define SAI2_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x5C000)
++#define QSPI0_BASE_ADDR                   (AIPS2_OFF_BASE_ADDR + 0x60000)
++#define QSPI1_BASE_ADDR                   (AIPS2_OFF_BASE_ADDR + 0x64000)
 +#else
- #define UART2_BASE                  (AIPS2_OFF_BASE_ADDR + 0x68000)
- #define UART3_BASE                  (AIPS2_OFF_BASE_ADDR + 0x6C000)
- #define UART4_BASE                  (AIPS2_OFF_BASE_ADDR + 0x70000)
- #define UART5_BASE                  (AIPS2_OFF_BASE_ADDR + 0x74000)
+ #define MIPI_CSI2_BASE_ADDR       (AIPS2_OFF_BASE_ADDR + 0x5C000)
+ #define MIPI_DSI_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x60000)
+ #define VDOA_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x64000)
 +#endif
+ #define UART2_BASE                (AIPS2_OFF_BASE_ADDR + 0x68000)
+ #define UART3_BASE                (AIPS2_OFF_BASE_ADDR + 0x6C000)
+ #define UART4_BASE                (AIPS2_OFF_BASE_ADDR + 0x70000)
+ #define UART5_BASE                (AIPS2_OFF_BASE_ADDR + 0x74000)
  #define IP2APB_USBPHY1_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x78000)
  #define IP2APB_USBPHY2_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x7C000)
  
- #define GIS_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x04000)
- #define DCIC1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x0C000)
- #define DCIC2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x10000)
- #define CSI1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x14000)
- #define PXP_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x18000)
- #define CSI2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x1C000)
- #define LCDIF1_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x20000)
- #define LCDIF2_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x24000)
- #define VADC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x28000)
- #define VDEC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x2C000)
- #define SPBA_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x3C000)
- #define AIPS3_CONFIG_BASE_ADDR      (AIPS3_ARB_BASE_ADDR + 0x7C000)
- #define ADC1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x80000)
- #define ADC2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x84000)
- #define WDOG3_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x88000)
- #define ECSPI5_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x8C000)
- #define HS_BASE_ADDR                (AIPS3_ARB_BASE_ADDR + 0x90000)
- #define MU_MCU_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x94000)
- #define CANFD_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x98000)
- #define MU_DSP_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x9C000)
- #define UART6_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA0000)
- #define PWM5_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA4000)
- #define PWM6_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA8000)
- #define PWM7_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xAC000)
- #define PWM8_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xB0000)
 +#ifdef CONFIG_MX6SX
- #define CHIP_REV_1_0                 0x10
- #define CHIP_REV_1_2                 0x12
- #define CHIP_REV_1_5                 0x15
++#define GIS_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x04000)
++#define DCIC1_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0x0C000)
++#define DCIC2_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0x10000)
++#define CSI1_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x14000)
++#define PXP_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x18000)
++#define CSI2_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x1C000)
++#define LCDIF1_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x20000)
++#define LCDIF2_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x24000)
++#define VADC_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x28000)
++#define VDEC_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x2C000)
++#define SPBA_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x3C000)
++#define AIPS3_CONFIG_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x7C000)
++#define ADC1_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x80000)
++#define ADC2_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x84000)
++#define WDOG3_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0x88000)
++#define ECSPI5_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x8C000)
++#define HS_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x90000)
++#define MU_MCU_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x94000)
++#define CANFD_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0x98000)
++#define MU_DSP_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x9C000)
++#define UART6_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0xA0000)
++#define PWM5_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xA4000)
++#define PWM6_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xA8000)
++#define PWM7_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xAC000)
++#define PWM8_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xB0000)
 +#endif
 +
- #define IRAM_SIZE                    0x00040000
+ #define CHIP_REV_1_0               0x10
++#define CHIP_REV_1_2               0x12
++#define CHIP_REV_1_5               0x15
 +#ifndef CONFIG_MX6SX
- #define IRAM_SIZE                    0x00020000
+ #define IRAM_SIZE                  0x00040000
 +#else
++#define IRAM_SIZE                  0x00020000
 +#endif
+ #define IMX_IIM_BASE               OCOTP_BASE_ADDR
  #define FEC_QUIRK_ENET_MAC
  
  #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
  #include <asm/types.h>
  
- extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
- #define SRC_SCR_CORE_1_RESET_OFFSET     14
- #define SRC_SCR_CORE_1_RESET_MASK       (1<<SRC_SCR_CORE_1_RESET_OFFSET)
- #define SRC_SCR_CORE_2_RESET_OFFSET     15
- #define SRC_SCR_CORE_2_RESET_MASK       (1<<SRC_SCR_CORE_2_RESET_OFFSET)
- #define SRC_SCR_CORE_3_RESET_OFFSET     16
- #define SRC_SCR_CORE_3_RESET_MASK       (1<<SRC_SCR_CORE_3_RESET_OFFSET)
- #define SRC_SCR_CORE_1_ENABLE_OFFSET    22
- #define SRC_SCR_CORE_1_ENABLE_MASK      (1<<SRC_SCR_CORE_1_ENABLE_OFFSET)
- #define SRC_SCR_CORE_2_ENABLE_OFFSET    23
- #define SRC_SCR_CORE_2_ENABLE_MASK      (1<<SRC_SCR_CORE_2_ENABLE_OFFSET)
- #define SRC_SCR_CORE_3_ENABLE_OFFSET    24
- #define SRC_SCR_CORE_3_ENABLE_MASK      (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
++#define SRC_SCR_CORE_1_RESET_OFFSET   14
++#define SRC_SCR_CORE_1_RESET_MASK     (1 << SRC_SCR_CORE_1_RESET_OFFSET)
++#define SRC_SCR_CORE_2_RESET_OFFSET   15
++#define SRC_SCR_CORE_2_RESET_MASK     (1 << SRC_SCR_CORE_2_RESET_OFFSET)
++#define SRC_SCR_CORE_3_RESET_OFFSET   16
++#define SRC_SCR_CORE_3_RESET_MASK     (1 << SRC_SCR_CORE_3_RESET_OFFSET)
++#define SRC_SCR_CORE_1_ENABLE_OFFSET  22
++#define SRC_SCR_CORE_1_ENABLE_MASK    (1 << SRC_SCR_CORE_1_ENABLE_OFFSET)
++#define SRC_SCR_CORE_2_ENABLE_OFFSET  23
++#define SRC_SCR_CORE_2_ENABLE_MASK    (1 << SRC_SCR_CORE_2_ENABLE_OFFSET)
++#define SRC_SCR_CORE_3_ENABLE_OFFSET  24
++#define SRC_SCR_CORE_3_ENABLE_MASK    (1 << SRC_SCR_CORE_3_ENABLE_OFFSET)
 +
 +/* WEIM registers */
 +struct weim {
 +      u32 cs0gcr1;
 +      u32 cs0gcr2;
 +      u32 cs0rcr1;
 +      u32 cs0rcr2;
 +      u32 cs0wcr1;
 +      u32 cs0wcr2;
 +
 +      u32 cs1gcr1;
 +      u32 cs1gcr2;
 +      u32 cs1rcr1;
 +      u32 cs1rcr2;
 +      u32 cs1wcr1;
 +      u32 cs1wcr2;
 +
 +      u32 cs2gcr1;
 +      u32 cs2gcr2;
 +      u32 cs2rcr1;
 +      u32 cs2rcr2;
 +      u32 cs2wcr1;
 +      u32 cs2wcr2;
 +
 +      u32 cs3gcr1;
 +      u32 cs3gcr2;
 +      u32 cs3rcr1;
 +      u32 cs3rcr2;
 +      u32 cs3wcr1;
 +      u32 cs3wcr2;
 +
 +      u32 unused[12];
 +
 +      u32 wcr;
 +      u32 wiar;
 +      u32 ear;
 +};
 +
  /* System Reset Controller (SRC) */
  struct src {
        u32     scr;
        u32     reserved1[2];
        u32     sisr;
        u32     simr;
-       u32     sbmr2;
-       u32     gpr1;
-       u32     gpr2;
-       u32     gpr3;
-       u32     gpr4;
-       u32     gpr5;
-       u32     gpr6;
-       u32     gpr7;
-       u32     gpr8;
-       u32     gpr9;
-       u32     gpr10;
+       u32     sbmr2;
+       u32     gpr1;
+       u32     gpr2;
+       u32     gpr3;
+       u32     gpr4;
+       u32     gpr5;
+       u32     gpr6;
+       u32     gpr7;
+       u32     gpr8;
+       u32     gpr9;
+       u32     gpr10;
  };
  
 +/* GPR1 bitfields */
 +#define IOMUXC_GPR1_ENET_CLK_SEL_OFFSET               21
 +#define IOMUXC_GPR1_ENET_CLK_SEL_MASK         (1 << IOMUXC_GPR1_ENET_CLK_SEL_OFFSET)
 +#define IOMUXC_GPR1_USB_OTG_ID_OFFSET         13
 +#define IOMUXC_GPR1_USB_OTG_ID_SEL_MASK               (1 << IOMUXC_GPR1_USB_OTG_ID_OFFSET)
 +
  /* GPR3 bitfields */
  #define IOMUXC_GPR3_GPU_DBG_OFFSET            29
  #define IOMUXC_GPR3_GPU_DBG_MASK              (3<<IOMUXC_GPR3_GPU_DBG_OFFSET)
  
  
  struct iomuxc {
-       u8 reserved[0x4000];
 +#ifdef CONFIG_MX6SX
++      u32 reserved[0x1000];
 +#endif
        u32 gpr[14];
 -      u32 omux[5];
 -      /* mux and pad registers */
 +};
 +
 +struct gpc {
 +      u32     cntr;
 +      u32     pgr;
 +      u32     imr1;
 +      u32     imr2;
 +      u32     imr3;
 +      u32     imr4;
 +      u32     isr1;
 +      u32     isr2;
 +      u32     isr3;
 +      u32     isr4;
  };
  
  #define IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET          20
@@@ -561,17 -395,15 +561,17 @@@ struct cspi_regs 
  #define MXC_CSPICTRL_RXOVF    (1 << 6)
  #define MXC_CSPIPERIOD_32KHZ  (1 << 15)
  #define MAX_SPI_BYTES 32
 +#define SPI_MAX_NUM   4
  
  /* Bit position inside CTRL register to be associated with SS */
  #define MXC_CSPICTRL_CHAN     18
  
  /* Bit position inside CON register to be associated with SS */
 -#define MXC_CSPICON_POL               4
 -#define MXC_CSPICON_PHA               0
 -#define MXC_CSPICON_SSPOL     12
 -#ifdef CONFIG_MX6SL
 +#define MXC_CSPICON_PHA               0  /* SCLK phase control */
 +#define MXC_CSPICON_POL               4  /* SCLK polarity */
 +#define MXC_CSPICON_SSPOL     12 /* SS polarity */
 +#define MXC_CSPICON_CTL               20 /* inactive state of SCLK */
 +#if defined(CONFIG_MX6SL) || defined(CONFIG_MX6DL)
  #define MXC_SPI_BASE_ADDRESSES \
        ECSPI1_BASE_ADDR, \
        ECSPI2_BASE_ADDR, \
  #endif
  
  struct ocotp_regs {
-       u32     ctrl;
-       u32     ctrl_set;
-       u32     ctrl_clr;
-       u32     ctrl_tog;
-       u32     timing;
-       u32     rsvd0[3];
-       u32     data;
-       u32     rsvd1[3];
-       u32     read_ctrl;
-       u32     rsvd2[3];
-       u32     read_fuse_data;
-       u32     rsvd3[3];
-       u32     sw_sticky;
-       u32     rsvd4[3];
-       u32     scs;
-       u32     scs_set;
-       u32     scs_clr;
-       u32     scs_tog;
-       u32     crc_addr;
-       u32     rsvd5[3];
-       u32     crc_value;
-       u32     rsvd6[3];
-       u32     version;
-       u32     rsvd7[0xdb];
+       mxs_reg_32(ctrl);
+       reg_32(timing);
+       reg_32(data);
+       reg_32(read_ctrl);
+       reg_32(fuse_data);
+       reg_32(sticky);
+       mxs_reg_32(scs);
+       reg_32(crc_addr);
+       reg_32(crc_value);
+       reg_32(version);
+       reg_32(rsvd[0x36]);
  
        struct fuse_bank {
-               u32     fuse_regs[0x20];
+               reg_32(fuse_regs[8]);
        } bank[16];
  };
  
  struct fuse_bank0_regs {
-       u32     lock;
-       u32     rsvd0[3];
-       u32     uid_low;
-       u32     rsvd1[3];
-       u32     uid_high;
-       u32     rsvd2[3];
-       u32     rsvd3[4];
-       u32     rsvd4[4];
-       u32     rsvd5[4];
-       u32     cfg5;
-       u32     rsvd6[3];
-       u32     rsvd7[4];
+       reg_32(misc_conf_lock);
 -      reg_32(cfg0);
 -      reg_32(cfg1);
++      union {
++              reg_32(cfg0);
++              reg_32(uid_low);
++      };
++      union {
++              reg_32(cfg1);
++              reg_32(uid_high);
++      };
+       reg_32(cfg2);
+       reg_32(cfg3);
+       reg_32(cfg4);
+       reg_32(cfg5);
+       reg_32(cfg6);
  };
  
 +#ifdef CONFIG_MX6SX
 +struct fuse_bank4_regs {
 +      u32 sjc_resp_low;
 +      u32 rsvd0[3];
 +      u32 sjc_resp_high;
 +      u32 rsvd1[3];
 +      u32 mac_addr_low;
 +      u32 rsvd2[3];
 +      u32 mac_addr_high;
 +      u32 rsvd3[3];
 +      u32 mac_addr2;
 +      u32 rsvd4[7];
 +      u32 gp1;
 +      u32 rsvd5[7];
 +};
 +#else
  struct fuse_bank4_regs {
-       u32     sjc_resp_low;
-       u32     rsvd0[3];
-       u32     sjc_resp_high;
-       u32     rsvd1[3];
-       u32     mac_addr_low;
-       u32     rsvd2[3];
-       u32     mac_addr_high;
-       u32     rsvd3[0xb];
-       u32     gp1;
-       u32     rsvd4[3];
-       u32     gp2;
-       u32     rsvd5[3];
+       reg_32(sjc_resp_low);
+       reg_32(sjc_resp_high);
+       reg_32(mac_addr_low);
+       reg_32(mac_addr_high);
+       reg_32(rsvd[2]);
+       reg_32(gp1);
+       reg_32(gp2);
+ };
+ struct fuse_bank5_regs {
+       reg_32(rsvd[5]);
+       reg_32(pad_settings);
+       reg_32(field_return);
  };
 +#endif
  
  struct aipstz_regs {
        u32     mprot0;
        u32     opacr4;
  };
  
 -struct iomuxc_base_regs {
 -      u32     gpr[14];        /* 0x000 */
 -      u32     obsrv[5];       /* 0x038 */
 -      u32     swmux_ctl[197]; /* 0x04c */
 -      u32     swpad_ctl[250]; /* 0x360 */
 -      u32     swgrp[26];      /* 0x748 */
 -      u32     daisy[104];     /* 0x7b0..94c */
 +struct anatop_regs {
-       u32     pll_sys;                /* 0x000 */
-       u32     pll_sys_set;            /* 0x004 */
-       u32     pll_sys_clr;            /* 0x008 */
-       u32     pll_sys_tog;            /* 0x00c */
-       u32     usb1_pll_480_ctrl;      /* 0x010 */
-       u32     usb1_pll_480_ctrl_set;  /* 0x014 */
-       u32     usb1_pll_480_ctrl_clr;  /* 0x018 */
-       u32     usb1_pll_480_ctrl_tog;  /* 0x01c */
-       u32     usb2_pll_480_ctrl;      /* 0x020 */
-       u32     usb2_pll_480_ctrl_set;  /* 0x024 */
-       u32     usb2_pll_480_ctrl_clr;  /* 0x028 */
-       u32     usb2_pll_480_ctrl_tog;  /* 0x02c */
-       u32     pll_528;                /* 0x030 */
-       u32     pll_528_set;            /* 0x034 */
-       u32     pll_528_clr;            /* 0x038 */
-       u32     pll_528_tog;            /* 0x03c */
-       u32     pll_528_ss;             /* 0x040 */
-       u32     rsvd0[3];
-       u32     pll_528_num;            /* 0x050 */
-       u32     rsvd1[3];
-       u32     pll_528_denom;          /* 0x060 */
-       u32     rsvd2[3];
-       u32     pll_audio;              /* 0x070 */
-       u32     pll_audio_set;          /* 0x074 */
-       u32     pll_audio_clr;          /* 0x078 */
-       u32     pll_audio_tog;          /* 0x07c */
-       u32     pll_audio_num;          /* 0x080 */
-       u32     rsvd3[3];
-       u32     pll_audio_denom;        /* 0x090 */
-       u32     rsvd4[3];
-       u32     pll_video;              /* 0x0a0 */
-       u32     pll_video_set;          /* 0x0a4 */
-       u32     pll_video_clr;          /* 0x0a8 */
-       u32     pll_video_tog;          /* 0x0ac */
-       u32     pll_video_num;          /* 0x0b0 */
-       u32     rsvd5[3];
-       u32     pll_video_denom;        /* 0x0c0 */
-       u32     rsvd6[3];
-       u32     pll_mlb;                /* 0x0d0 */
-       u32     pll_mlb_set;            /* 0x0d4 */
-       u32     pll_mlb_clr;            /* 0x0d8 */
-       u32     pll_mlb_tog;            /* 0x0dc */
-       u32     pll_enet;               /* 0x0e0 */
-       u32     pll_enet_set;           /* 0x0e4 */
-       u32     pll_enet_clr;           /* 0x0e8 */
-       u32     pll_enet_tog;           /* 0x0ec */
-       u32     pfd_480;                /* 0x0f0 */
-       u32     pfd_480_set;            /* 0x0f4 */
-       u32     pfd_480_clr;            /* 0x0f8 */
-       u32     pfd_480_tog;            /* 0x0fc */
-       u32     pfd_528;                /* 0x100 */
-       u32     pfd_528_set;            /* 0x104 */
-       u32     pfd_528_clr;            /* 0x108 */
-       u32     pfd_528_tog;            /* 0x10c */
-       u32     reg_1p1;                /* 0x110 */
-       u32     reg_1p1_set;            /* 0x114 */
-       u32     reg_1p1_clr;            /* 0x118 */
-       u32     reg_1p1_tog;            /* 0x11c */
-       u32     reg_3p0;                /* 0x120 */
-       u32     reg_3p0_set;            /* 0x124 */
-       u32     reg_3p0_clr;            /* 0x128 */
-       u32     reg_3p0_tog;            /* 0x12c */
-       u32     reg_2p5;                /* 0x130 */
-       u32     reg_2p5_set;            /* 0x134 */
-       u32     reg_2p5_clr;            /* 0x138 */
-       u32     reg_2p5_tog;            /* 0x13c */
-       u32     reg_core;               /* 0x140 */
-       u32     reg_core_set;           /* 0x144 */
-       u32     reg_core_clr;           /* 0x148 */
-       u32     reg_core_tog;           /* 0x14c */
-       u32     ana_misc0;              /* 0x150 */
-       u32     ana_misc0_set;          /* 0x154 */
-       u32     ana_misc0_clr;          /* 0x158 */
-       u32     ana_misc0_tog;          /* 0x15c */
-       u32     ana_misc1;              /* 0x160 */
-       u32     ana_misc1_set;          /* 0x164 */
-       u32     ana_misc1_clr;          /* 0x168 */
-       u32     ana_misc1_tog;          /* 0x16c */
-       u32     ana_misc2;              /* 0x170 */
-       u32     ana_misc2_set;          /* 0x174 */
-       u32     ana_misc2_clr;          /* 0x178 */
-       u32     ana_misc2_tog;          /* 0x17c */
-       u32     tempsense0;             /* 0x180 */
-       u32     tempsense0_set;         /* 0x184 */
-       u32     tempsense0_clr;         /* 0x188 */
-       u32     tempsense0_tog;         /* 0x18c */
-       u32     tempsense1;             /* 0x190 */
-       u32     tempsense1_set;         /* 0x194 */
-       u32     tempsense1_clr;         /* 0x198 */
-       u32     tempsense1_tog;         /* 0x19c */
-       u32     usb1_vbus_detect;       /* 0x1a0 */
-       u32     usb1_vbus_detect_set;   /* 0x1a4 */
-       u32     usb1_vbus_detect_clr;   /* 0x1a8 */
-       u32     usb1_vbus_detect_tog;   /* 0x1ac */
-       u32     usb1_chrg_detect;       /* 0x1b0 */
-       u32     usb1_chrg_detect_set;   /* 0x1b4 */
-       u32     usb1_chrg_detect_clr;   /* 0x1b8 */
-       u32     usb1_chrg_detect_tog;   /* 0x1bc */
-       u32     usb1_vbus_det_stat;     /* 0x1c0 */
-       u32     usb1_vbus_det_stat_set; /* 0x1c4 */
-       u32     usb1_vbus_det_stat_clr; /* 0x1c8 */
-       u32     usb1_vbus_det_stat_tog; /* 0x1cc */
-       u32     usb1_chrg_det_stat;     /* 0x1d0 */
-       u32     usb1_chrg_det_stat_set; /* 0x1d4 */
-       u32     usb1_chrg_det_stat_clr; /* 0x1d8 */
-       u32     usb1_chrg_det_stat_tog; /* 0x1dc */
-       u32     usb1_loopback;          /* 0x1e0 */
-       u32     usb1_loopback_set;      /* 0x1e4 */
-       u32     usb1_loopback_clr;      /* 0x1e8 */
-       u32     usb1_loopback_tog;      /* 0x1ec */
-       u32     usb1_misc;              /* 0x1f0 */
-       u32     usb1_misc_set;          /* 0x1f4 */
-       u32     usb1_misc_clr;          /* 0x1f8 */
-       u32     usb1_misc_tog;          /* 0x1fc */
-       u32     usb2_vbus_detect;       /* 0x200 */
-       u32     usb2_vbus_detect_set;   /* 0x204 */
-       u32     usb2_vbus_detect_clr;   /* 0x208 */
-       u32     usb2_vbus_detect_tog;   /* 0x20c */
-       u32     usb2_chrg_detect;       /* 0x210 */
-       u32     usb2_chrg_detect_set;   /* 0x214 */
-       u32     usb2_chrg_detect_clr;   /* 0x218 */
-       u32     usb2_chrg_detect_tog;   /* 0x21c */
-       u32     usb2_vbus_det_stat;     /* 0x220 */
-       u32     usb2_vbus_det_stat_set; /* 0x224 */
-       u32     usb2_vbus_det_stat_clr; /* 0x228 */
-       u32     usb2_vbus_det_stat_tog; /* 0x22c */
-       u32     usb2_chrg_det_stat;     /* 0x230 */
-       u32     usb2_chrg_det_stat_set; /* 0x234 */
-       u32     usb2_chrg_det_stat_clr; /* 0x238 */
-       u32     usb2_chrg_det_stat_tog; /* 0x23c */
-       u32     usb2_loopback;          /* 0x240 */
-       u32     usb2_loopback_set;      /* 0x244 */
-       u32     usb2_loopback_clr;      /* 0x248 */
-       u32     usb2_loopback_tog;      /* 0x24c */
-       u32     usb2_misc;              /* 0x250 */
-       u32     usb2_misc_set;          /* 0x254 */
-       u32     usb2_misc_clr;          /* 0x258 */
-       u32     usb2_misc_tog;          /* 0x25c */
-       u32     digprog;                /* 0x260 */
-       u32     reserved1[7];
-       u32     digprog_sololite;       /* 0x280 */
++      mxs_reg_32(pll_arm);            /* 0x000 */
++      mxs_reg_32(usb1_pll_480_ctrl);  /* 0x010 */
++      mxs_reg_32(usb2_pll_480_ctrl);  /* 0x020 */
++      mxs_reg_32(pll_528);            /* 0x030 */
++      reg_32(pll_528_ss);             /* 0x040 */
++      reg_32(pll_528_num);            /* 0x050 */
++      reg_32(pll_528_denom);          /* 0x060 */
++      mxs_reg_32(pll_audio);          /* 0x070 */
++      reg_32(pll_audio_num);          /* 0x080 */
++      reg_32(pll_audio_denom);        /* 0x090 */
++      mxs_reg_32(pll_video);          /* 0x0a0 */
++      reg_32(pll_video_num);          /* 0x0b0 */
++      reg_32(pll_video_denom);        /* 0x0c0 */
++      mxs_reg_32(pll_mlb);            /* 0x0d0 */
++      mxs_reg_32(pll_enet);           /* 0x0e0 */
++      mxs_reg_32(pfd_480);            /* 0x0f0 */
++      mxs_reg_32(pfd_528);            /* 0x100 */
++      mxs_reg_32(reg_1p1);            /* 0x110 */
++      mxs_reg_32(reg_3p0);            /* 0x120 */
++      mxs_reg_32(reg_2p5);            /* 0x130 */
++      mxs_reg_32(reg_core);           /* 0x140 */
++      mxs_reg_32(ana_misc0);          /* 0x150 */
++      mxs_reg_32(ana_misc1);          /* 0x160 */
++      mxs_reg_32(ana_misc2);          /* 0x170 */
++      mxs_reg_32(tempsense0);         /* 0x180 */
++      mxs_reg_32(tempsense1);         /* 0x190 */
++      mxs_reg_32(usb1_vbus_detect);   /* 0x1a0 */
++      mxs_reg_32(usb1_chrg_detect);   /* 0x1b0 */
++      mxs_reg_32(usb1_vbus_det_stat); /* 0x1c0 */
++      mxs_reg_32(usb1_chrg_det_stat); /* 0x1d0 */
++      mxs_reg_32(usb1_loopback);      /* 0x1e0 */
++      mxs_reg_32(usb1_misc);          /* 0x1f0 */
++      mxs_reg_32(usb2_vbus_detect);   /* 0x200 */
++      mxs_reg_32(usb2_chrg_detect);   /* 0x210 */
++      mxs_reg_32(usb2_vbus_det_stat); /* 0x220 */
++      mxs_reg_32(usb2_chrg_det_stat); /* 0x230 */
++      mxs_reg_32(usb2_loopback);      /* 0x240 */
++      mxs_reg_32(usb2_misc);          /* 0x250 */
++      reg_32(digprog);                /* 0x260 */
++      reg_32(rsrvd);                  /* 0x270 */
++      reg_32(digprog_sololite);       /* 0x280 */
  };
  
- #define ANATOP_PFD_FRAC_SHIFT(n)      ((n)*8)
- #define ANATOP_PFD_FRAC_MASK(n)       (0x3f<<ANATOP_PFD_FRAC_SHIFT(n))
- #define ANATOP_PFD_STABLE_SHIFT(n)    (6+((n)*8))
- #define ANATOP_PFD_STABLE_MASK(n)     (1<<ANATOP_PFD_STABLE_SHIFT(n))
- #define ANATOP_PFD_CLKGATE_SHIFT(n)   (7+((n)*8))
- #define ANATOP_PFD_CLKGATE_MASK(n)    (1<<ANATOP_PFD_CLKGATE_SHIFT(n))
++#define ANATOP_PFD_FRAC_SHIFT(n)      ((n) * 8)
++#define ANATOP_PFD_FRAC_MASK(n)               (0x3f << ANATOP_PFD_FRAC_SHIFT(n))
++#define ANATOP_PFD_STABLE_SHIFT(n)    (6 + ((n) * 8))
++#define ANATOP_PFD_STABLE_MASK(n)     (1 << ANATOP_PFD_STABLE_SHIFT(n))
++#define ANATOP_PFD_CLKGATE_SHIFT(n)   (7 + ((n) * 8))
++#define ANATOP_PFD_CLKGATE_MASK(n)    (1 << ANATOP_PFD_CLKGATE_SHIFT(n))
 +
  struct wdog_regs {
        u16     wcr;    /* Control */
        u16     wsr;    /* Service */
        u16     wmcr;   /* Miscellaneous Control */
  };
  
- #define PWMCR_PRESCALER(x)    (((x - 1) & 0xFFF) << 4)
++#define PWMCR_PRESCALER(x)    ((((x) - 1) & 0xFFF) << 4)
 +#define PWMCR_DOZEEN          (1 << 24)
 +#define PWMCR_WAITEN          (1 << 23)
 +#define PWMCR_DBGEN           (1 << 22)
 +#define PWMCR_CLKSRC_IPG_HIGH (2 << 16)
 +#define PWMCR_CLKSRC_IPG      (1 << 16)
 +#define PWMCR_EN              (1 << 0)
 +
 +struct pwm_regs {
 +      u32     cr;
 +      u32     sr;
 +      u32     ir;
 +      u32     sar;
 +      u32     pr;
 +      u32     cnr;
 +};
  #endif /* __ASSEMBLER__*/
 -
  #endif /* __ASM_ARCH_MX6_IMX_REGS_H__ */
index 28ba84415f05b667d24dd329f1a1953189e67a53,d263560a1a8c87f383858a1114f5261bfe2162a3..8e92e8567fe5fe22e9a3465ade77ca7375cf353b
@@@ -9,25 -9,24 +9,30 @@@
  #define _SYS_PROTO_H_
  
  #include <asm/imx-common/regs-common.h>
 +#include "../arch-imx/cpu.h"
  
 -#define MXC_CPU_MX51          0x51
 -#define MXC_CPU_MX53          0x53
 -#define MXC_CPU_MX6SL         0x60
 -#define MXC_CPU_MX6DL         0x61
 -#define MXC_CPU_MX6SOLO               0x62
 -#define MXC_CPU_MX6Q          0x63
 +#define soc_rev() (get_cpu_rev() & 0xFF)
 +#define is_soc_rev(rev)        (soc_rev() - rev)
  
 -#define is_soc_rev(rev)       ((get_cpu_rev() & 0xFF) - rev)
 +u32 get_nr_cpus(void);
  u32 get_cpu_rev(void);
 +
 +/* returns MXC_CPU_ value */
 +#define cpu_type(rev) (((rev) >> 12)&0xff)
 +
 +/* both macros return/take MXC_CPU_ constants */
 +#define get_cpu_type()        (cpu_type(get_cpu_rev()))
 +#define is_cpu_type(cpu) (get_cpu_type() == cpu)
 +
  const char *get_imx_type(u32 imxtype);
  unsigned imx_ddr_size(void);
 +void set_chipselect_size(int const);
  
+ struct mxs_register_32;
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
  /*
   * Initializes on-chip ethernet controllers.
   * to override, implement board_eth_init()
@@@ -44,4 -43,7 +49,7 @@@ int mxs_wait_mask_set(struct mxs_regist
  int mxs_wait_mask_clr(struct mxs_register_32 *reg,
                       uint32_t mask,
                       unsigned int timeout);
+ int read_cpu_temperature(void);
+ int check_cpu_temperature(int boot);
  #endif
index 062f3de1d05bfd4de1011762b55fbb6311c84fc9,3f4c108942d27108ce4e7f50adf25b7f7b9ff8e8..407055c9095f170d965f867b980e18d728c63eda
@@@ -10,7 -10,7 +10,7 @@@
  #ifndef __SYS_PROTO_H__
  #define __SYS_PROTO_H__
  
 -struct mxs_register_32;
 +#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,
@@@ -22,6 -22,8 +22,8 @@@ int mxs_wait_mask_clr(struct mxs_regist
  
  int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int));
  
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
  #ifdef CONFIG_SPL_BUILD
  
  #if defined(CONFIG_MX23)
@@@ -30,9 -32,8 +32,9 @@@
  #include <asm/arch/iomux-mx28.h>
  #endif
  
 -void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
 -                      const unsigned int iomux_size);
 +void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
 +                       const iomux_cfg_t *iomux_setup,
 +                       const unsigned int iomux_size);
  #endif
  
  struct mxs_pair {
@@@ -48,7 -49,6 +50,7 @@@ static const struct mxs_pair mxs_boot_m
        { 0x02, 0x1f, "SSP SPI #1, master, NOR" },
        { 0x03, 0x1f, "SSP SPI #2, master, NOR" },
        { 0x04, 0x1f, "NAND" },
 +      { 0x06, 0x1f, "JTAG" },
        { 0x08, 0x1f, "SSP SPI #3, master, EEPROM" },
        { 0x09, 0x1f, "SSP SD/MMC #0" },
        { 0x0a, 0x1f, "SSP SD/MMC #1" },
@@@ -63,7 -63,6 +65,7 @@@
        { 0x13, 0x1f, "SSP SPI #3, master, 1V8 NOR" },
        { 0x04, 0x1f, "NAND, 3V3" },
        { 0x14, 0x1f, "NAND, 1V8" },
 +      { 0x06, 0x1f, "JTAG" },
        { 0x08, 0x1f, "SSP SPI #3, master, 3V3 EEPROM" },
        { 0x18, 0x1f, "SSP SPI #3, master, 1V8 EEPROM" },
        { 0x09, 0x1f, "SSP SD/MMC #0, 3V3" },
index 2fe5776c6cf390777f55c632068723e64d44034b,56cbd07431ec568a6265151f527b40b92ca61ad6..cd4fc9075cd87e6d673ef3ad663c52145b32343c
  #define _EMIF_H_
  #include <asm/types.h>
  #include <common.h>
 +#include <asm/io.h>
  
  /* Base address */
  #define EMIF1_BASE                            0x4c000000
  #define EMIF2_BASE                            0x4d000000
  
 +#define EMIF_4D                                       0x4
 +#define EMIF_4D5                              0x5
 +
  /* Registers shifts, masks and values */
  
  /* EMIF_MOD_ID_REV */
        (0xFF << EMIF_SYS_ADDR_SHIFT))
  
  #define EMIF_EXT_PHY_CTRL_TIMING_REG  0x5
 -#define EMIF_EXT_PHY_CTRL_CONST_REG   0x14
  
  /* Reg mapping structure */
  struct emif_reg_struct {
-       u32 emif_mod_id_rev;
-       u32 emif_status;
-       u32 emif_sdram_config;
-       u32 emif_lpddr2_nvm_config;
-       u32 emif_sdram_ref_ctrl;
-       u32 emif_sdram_ref_ctrl_shdw;
-       u32 emif_sdram_tim_1;
-       u32 emif_sdram_tim_1_shdw;
-       u32 emif_sdram_tim_2;
-       u32 emif_sdram_tim_2_shdw;
-       u32 emif_sdram_tim_3;
-       u32 emif_sdram_tim_3_shdw;
-       u32 emif_lpddr2_nvm_tim;
-       u32 emif_lpddr2_nvm_tim_shdw;
-       u32 emif_pwr_mgmt_ctrl;
-       u32 emif_pwr_mgmt_ctrl_shdw;
-       u32 emif_lpddr2_mode_reg_data;
-       u32 padding1[1];
-       u32 emif_lpddr2_mode_reg_data_es2;
-       u32 padding11[1];
-       u32 emif_lpddr2_mode_reg_cfg;
-       u32 emif_l3_config;
-       u32 emif_l3_cfg_val_1;
-       u32 emif_l3_cfg_val_2;
-       u32 emif_iodft_tlgc;
-       u32 padding2[7];
-       u32 emif_perf_cnt_1;
-       u32 emif_perf_cnt_2;
-       u32 emif_perf_cnt_cfg;
-       u32 emif_perf_cnt_sel;
-       u32 emif_perf_cnt_tim;
-       u32 padding3;
-       u32 emif_read_idlectrl;
-       u32 emif_read_idlectrl_shdw;
-       u32 padding4;
-       u32 emif_irqstatus_raw_sys;
-       u32 emif_irqstatus_raw_ll;
-       u32 emif_irqstatus_sys;
-       u32 emif_irqstatus_ll;
-       u32 emif_irqenable_set_sys;
-       u32 emif_irqenable_set_ll;
-       u32 emif_irqenable_clr_sys;
-       u32 emif_irqenable_clr_ll;
-       u32 padding5;
-       u32 emif_zq_config;
-       u32 emif_temp_alert_config;
-       u32 emif_l3_err_log;
-       u32 emif_rd_wr_lvl_rmp_win;
-       u32 emif_rd_wr_lvl_rmp_ctl;
-       u32 emif_rd_wr_lvl_ctl;
-       u32 padding6[1];
-       u32 emif_ddr_phy_ctrl_1;
-       u32 emif_ddr_phy_ctrl_1_shdw;
-       u32 emif_ddr_phy_ctrl_2;
-       u32 padding7[4];
-       u32 emif_prio_class_serv_map;
-       u32 emif_connect_id_serv_1_map;
-       u32 emif_connect_id_serv_2_map;
-       u32 padding8[5];
-       u32 emif_rd_wr_exec_thresh;
-       u32 emif_cos_config;
-       u32 padding9[6];
-       u32 emif_ddr_phy_status[21];
-       u32 padding10[27];
-       u32 emif_ddr_ext_phy_ctrl_1;
-       u32 emif_ddr_ext_phy_ctrl_1_shdw;
-       u32 emif_ddr_ext_phy_ctrl_2;
-       u32 emif_ddr_ext_phy_ctrl_2_shdw;
-       u32 emif_ddr_ext_phy_ctrl_3;
-       u32 emif_ddr_ext_phy_ctrl_3_shdw;
-       u32 emif_ddr_ext_phy_ctrl_4;
-       u32 emif_ddr_ext_phy_ctrl_4_shdw;
-       u32 emif_ddr_ext_phy_ctrl_5;
-       u32 emif_ddr_ext_phy_ctrl_5_shdw;
-       u32 emif_ddr_ext_phy_ctrl_6;
-       u32 emif_ddr_ext_phy_ctrl_6_shdw;
-       u32 emif_ddr_ext_phy_ctrl_7;
-       u32 emif_ddr_ext_phy_ctrl_7_shdw;
-       u32 emif_ddr_ext_phy_ctrl_8;
-       u32 emif_ddr_ext_phy_ctrl_8_shdw;
-       u32 emif_ddr_ext_phy_ctrl_9;
-       u32 emif_ddr_ext_phy_ctrl_9_shdw;
-       u32 emif_ddr_ext_phy_ctrl_10;
-       u32 emif_ddr_ext_phy_ctrl_10_shdw;
-       u32 emif_ddr_ext_phy_ctrl_11;
-       u32 emif_ddr_ext_phy_ctrl_11_shdw;
-       u32 emif_ddr_ext_phy_ctrl_12;
-       u32 emif_ddr_ext_phy_ctrl_12_shdw;
-       u32 emif_ddr_ext_phy_ctrl_13;
-       u32 emif_ddr_ext_phy_ctrl_13_shdw;
-       u32 emif_ddr_ext_phy_ctrl_14;
-       u32 emif_ddr_ext_phy_ctrl_14_shdw;
-       u32 emif_ddr_ext_phy_ctrl_15;
-       u32 emif_ddr_ext_phy_ctrl_15_shdw;
-       u32 emif_ddr_ext_phy_ctrl_16;
-       u32 emif_ddr_ext_phy_ctrl_16_shdw;
-       u32 emif_ddr_ext_phy_ctrl_17;
-       u32 emif_ddr_ext_phy_ctrl_17_shdw;
-       u32 emif_ddr_ext_phy_ctrl_18;
-       u32 emif_ddr_ext_phy_ctrl_18_shdw;
-       u32 emif_ddr_ext_phy_ctrl_19;
-       u32 emif_ddr_ext_phy_ctrl_19_shdw;
-       u32 emif_ddr_ext_phy_ctrl_20;
-       u32 emif_ddr_ext_phy_ctrl_20_shdw;
-       u32 emif_ddr_ext_phy_ctrl_21;
-       u32 emif_ddr_ext_phy_ctrl_21_shdw;
-       u32 emif_ddr_ext_phy_ctrl_22;
-       u32 emif_ddr_ext_phy_ctrl_22_shdw;
-       u32 emif_ddr_ext_phy_ctrl_23;
-       u32 emif_ddr_ext_phy_ctrl_23_shdw;
-       u32 emif_ddr_ext_phy_ctrl_24;
-       u32 emif_ddr_ext_phy_ctrl_24_shdw;
-       u32 padding[22];
-       u32 emif_ddr_fifo_misaligned_clear_1;
-       u32 emif_ddr_fifo_misaligned_clear_2;
+       u32 emif_mod_id_rev;                    /* 0x000 */
+       u32 emif_status;                        /* 0x004 */
+       u32 emif_sdram_config;                  /* 0x008 */
+       u32 emif_lpddr2_nvm_config;             /* 0x00c */
+       u32 emif_sdram_ref_ctrl;                /* 0x010 */
+       u32 emif_sdram_ref_ctrl_shdw;           /* 0x014 */
+       u32 emif_sdram_tim_1;                   /* 0x018 */
+       u32 emif_sdram_tim_1_shdw;              /* 0x01c */
+       u32 emif_sdram_tim_2;                   /* 0x020 */
+       u32 emif_sdram_tim_2_shdw;              /* 0x024 */
+       u32 emif_sdram_tim_3;                   /* 0x028 */
+       u32 emif_sdram_tim_3_shdw;              /* 0x02c */
+       u32 emif_lpddr2_nvm_tim;                /* 0x030 */
+       u32 emif_lpddr2_nvm_tim_shdw;           /* 0x034 */
+       u32 emif_pwr_mgmt_ctrl;                 /* 0x038 */
+       u32 emif_pwr_mgmt_ctrl_shdw;            /* 0x03c */
+       u32 emif_lpddr2_mode_reg_data;          /* 0x040 */
+       u32 padding1[1];                        /* 0x044 */
+       u32 emif_lpddr2_mode_reg_data_es2;      /* 0x048 */
+       u32 padding11[1];                       /* 0x04c */
+       u32 emif_lpddr2_mode_reg_cfg;           /* 0x050 */
+       u32 emif_l3_config;                     /* 0x054 */
+       u32 emif_l3_cfg_val_1;                  /* 0x058 */
+       u32 emif_l3_cfg_val_2;                  /* 0x05c */
+       u32 emif_iodft_tlgc;                    /* 0x060 */
+       u32 padding2[7];                        /* 0x064 */
+       u32 emif_perf_cnt_1;                    /* 0x080 */
+       u32 emif_perf_cnt_2;                    /* 0x084 */
+       u32 emif_perf_cnt_cfg;                  /* 0x088 */
+       u32 emif_perf_cnt_sel;                  /* 0x08c */
+       u32 emif_perf_cnt_tim;                  /* 0x090 */
+       u32 padding3;                           /* 0x094 */
+       u32 emif_read_idlectrl;                 /* 0x098 */
+       u32 emif_read_idlectrl_shdw;            /* 0x09c */
+       u32 padding4;                           /* 0x0a0 */
+       u32 emif_irqstatus_raw_sys;             /* 0x0a4 */
+       u32 emif_irqstatus_raw_ll;              /* 0x0a8 */
+       u32 emif_irqstatus_sys;                 /* 0x0ac */
+       u32 emif_irqstatus_ll;                  /* 0x0b0 */
+       u32 emif_irqenable_set_sys;             /* 0x0b4 */
+       u32 emif_irqenable_set_ll;              /* 0x0b8 */
+       u32 emif_irqenable_clr_sys;             /* 0x0bc */
+       u32 emif_irqenable_clr_ll;              /* 0x0c0 */
+       u32 padding5;                           /* 0x0c4 */
+       u32 emif_zq_config;                     /* 0x0c8 */
+       u32 emif_temp_alert_config;             /* 0x0cc */
+       u32 emif_l3_err_log;                    /* 0x0d0 */
+       u32 emif_rd_wr_lvl_rmp_win;             /* 0x0d4 */
+       u32 emif_rd_wr_lvl_rmp_ctl;             /* 0x0d8 */
+       u32 emif_rd_wr_lvl_ctl;                 /* 0x0dc */
+       u32 padding6[1];                        /* 0x0e0 */
+       u32 emif_ddr_phy_ctrl_1;                /* 0x0e4 */
+       u32 emif_ddr_phy_ctrl_1_shdw;           /* 0x0e8 */
+       u32 emif_ddr_phy_ctrl_2;                /* 0x0ec */
 -      u32 padding7[12];                       /* 0x0f0 */
++      u32 padding7[4];                        /* 0x0f0 */
++      u32 emif_prio_class_serv_map;           /* 0x100 */
++      u32 emif_connect_id_serv_1_map;         /* 0x104 */
++      u32 emif_connect_id_serv_2_map;         /* 0x108 */
++      u32 padding8[5];                        /* 0x10c */
+       u32 emif_rd_wr_exec_thresh;             /* 0x120 */
 -      u32 padding8[55];                       /* 0x124 */
++      u32 padding9[6];                        /* 0x124 */
++      u32 emif_ddr_phy_status[21];            /* 0x13c */
++      u32 padding10[27];                      /* 0x1fc */
+       u32 emif_ddr_ext_phy_ctrl_1;            /* 0x200 */
+       u32 emif_ddr_ext_phy_ctrl_1_shdw;       /* 0x204 */
+       u32 emif_ddr_ext_phy_ctrl_2;            /* 0x248 */
+       u32 emif_ddr_ext_phy_ctrl_2_shdw;       /* 0x24c */
+       u32 emif_ddr_ext_phy_ctrl_3;            /* 0x200 */
+       u32 emif_ddr_ext_phy_ctrl_3_shdw;       /* 0x204 */
+       u32 emif_ddr_ext_phy_ctrl_4;            /* 0x208 */
+       u32 emif_ddr_ext_phy_ctrl_4_shdw;       /* 0x20c */
+       u32 emif_ddr_ext_phy_ctrl_5;            /* 0x210 */
+       u32 emif_ddr_ext_phy_ctrl_5_shdw;       /* 0x214 */
+       u32 emif_ddr_ext_phy_ctrl_6;            /* 0x218 */
+       u32 emif_ddr_ext_phy_ctrl_6_shdw;       /* 0x21c */
+       u32 emif_ddr_ext_phy_ctrl_7;            /* 0x220 */
+       u32 emif_ddr_ext_phy_ctrl_7_shdw;       /* 0x224 */
+       u32 emif_ddr_ext_phy_ctrl_8;            /* 0x228 */
+       u32 emif_ddr_ext_phy_ctrl_8_shdw;       /* 0x22c */
+       u32 emif_ddr_ext_phy_ctrl_9;            /* 0x230 */
+       u32 emif_ddr_ext_phy_ctrl_9_shdw;       /* 0x234 */
+       u32 emif_ddr_ext_phy_ctrl_10;           /* 0x238 */
+       u32 emif_ddr_ext_phy_ctrl_10_shdw;      /* 0x23c */
+       u32 emif_ddr_ext_phy_ctrl_11;           /* 0x240 */
+       u32 emif_ddr_ext_phy_ctrl_11_shdw;      /* 0x244 */
+       u32 emif_ddr_ext_phy_ctrl_12;           /* 0x248 */
+       u32 emif_ddr_ext_phy_ctrl_12_shdw;      /* 0x24c */
+       u32 emif_ddr_ext_phy_ctrl_13;           /* 0x250 */
+       u32 emif_ddr_ext_phy_ctrl_13_shdw;      /* 0x254 */
+       u32 emif_ddr_ext_phy_ctrl_14;           /* 0x258 */
+       u32 emif_ddr_ext_phy_ctrl_14_shdw;      /* 0x25c */
+       u32 emif_ddr_ext_phy_ctrl_15;           /* 0x260 */
+       u32 emif_ddr_ext_phy_ctrl_15_shdw;      /* 0x264 */
+       u32 emif_ddr_ext_phy_ctrl_16;           /* 0x268 */
+       u32 emif_ddr_ext_phy_ctrl_16_shdw;      /* 0x26c */
+       u32 emif_ddr_ext_phy_ctrl_17;           /* 0x270 */
+       u32 emif_ddr_ext_phy_ctrl_17_shdw;      /* 0x274 */
+       u32 emif_ddr_ext_phy_ctrl_18;           /* 0x278 */
+       u32 emif_ddr_ext_phy_ctrl_18_shdw;      /* 0x27c */
+       u32 emif_ddr_ext_phy_ctrl_19;           /* 0x280 */
+       u32 emif_ddr_ext_phy_ctrl_19_shdw;      /* 0x284 */
+       u32 emif_ddr_ext_phy_ctrl_20;           /* 0x288 */
+       u32 emif_ddr_ext_phy_ctrl_20_shdw;      /* 0x28c */
+       u32 emif_ddr_ext_phy_ctrl_21;           /* 0x290 */
+       u32 emif_ddr_ext_phy_ctrl_21_shdw;      /* 0x294 */
+       u32 emif_ddr_ext_phy_ctrl_22;           /* 0x298 */
+       u32 emif_ddr_ext_phy_ctrl_22_shdw;      /* 0x29c */
+       u32 emif_ddr_ext_phy_ctrl_23;           /* 0x2a0 */
+       u32 emif_ddr_ext_phy_ctrl_23_shdw;      /* 0x2a4 */
+       u32 emif_ddr_ext_phy_ctrl_24;           /* 0x2a8 */
+       u32 emif_ddr_ext_phy_ctrl_24_shdw;      /* 0x2ac */
++      u32 padding[22];                        /* 0x2b0 */
++      u32 emif_ddr_fifo_misaligned_clear_1;   /* 0x308 */
++      u32 emif_ddr_fifo_misaligned_clear_2;   /* 0x30c */
  };
  
  struct dmm_lisa_map_regs {
        ((REG_CS_TIM << EMIF_REG_CS_TIM_SHIFT) & EMIF_REG_CS_TIM_MASK)|\
        ((REG_SR_TIM << EMIF_REG_SR_TIM_SHIFT) & EMIF_REG_SR_TIM_MASK)|\
        ((REG_PD_TIM << EMIF_REG_PD_TIM_SHIFT) & EMIF_REG_PD_TIM_MASK)|\
 -      ((REG_PD_TIM << EMIF_REG_PD_TIM_SHIFT) & EMIF_REG_PD_TIM_MASK)|\
        ((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)\
                        & EMIF_REG_LP_MODE_MASK) |\
        ((DPD_DISABLE << EMIF_REG_DPD_EN_SHIFT)\
                        & EMIF_REG_CS_TIM_SHDW_MASK) |\
        ((REG_SR_TIM << EMIF_REG_SR_TIM_SHDW_SHIFT)\
                        & EMIF_REG_SR_TIM_SHDW_MASK) |\
 -      ((REG_PD_TIM << EMIF_REG_PD_TIM_SHDW_SHIFT)\
 -                      & EMIF_REG_PD_TIM_SHDW_MASK) |\
        ((REG_PD_TIM << EMIF_REG_PD_TIM_SHDW_SHIFT)\
                        & EMIF_REG_PD_TIM_SHDW_MASK))
  
@@@ -1139,10 -1129,6 +1138,10 @@@ struct emif_regs 
        u32 emif_rd_wr_lvl_rmp_ctl;
        u32 emif_rd_wr_lvl_ctl;
        u32 emif_rd_wr_exec_thresh;
 +      u32 emif_prio_class_serv_map;
 +      u32 emif_connect_id_serv_1_map;
 +      u32 emif_connect_id_serv_2_map;
 +      u32 emif_cos_config;
  };
  
  struct lpddr2_mr_regs {
        s8 mr16;
  };
  
 +struct read_write_regs {
 +      u32 read_reg;
 +      u32 write_reg;
 +};
 +
 +static inline u32 get_emif_rev(u32 base)
 +{
 +      struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
 +
 +      return (readl(&emif->emif_mod_id_rev) & EMIF_REG_MAJOR_REVISION_MASK)
 +              >> EMIF_REG_MAJOR_REVISION_SHIFT;
 +}
 +
 +/*
 + * Get SDRAM type connected to EMIF.
 + * Assuming similar SDRAM parts are connected to both EMIF's
 + * which is typically the case. So it is sufficient to get
 + * SDRAM type from EMIF1.
 + */
 +static inline u32 emif_sdram_type(void)
 +{
 +      struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
 +
 +      return (readl(&emif->emif_sdram_config) &
 +              EMIF_REG_SDRAM_TYPE_MASK) >> EMIF_REG_SDRAM_TYPE_SHIFT;
 +}
 +
  /* assert macros */
  #if defined(DEBUG)
- #define emif_assert(c)        ({ if (!(c)) for (;;); })
+ #define emif_assert(c)        ({ if (!(c)) hang(); })
  #else
- #define emif_assert(c)        ({ if (0) hang(); })
+ #define emif_assert(c)        (c)
  #endif
  
  #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
@@@ -1208,5 -1167,4 +1207,5 @@@ extern u32 *const T_den
  
  void config_data_eye_leveling_samples(u32 emif_base);
  u32 emif_sdram_type(void);
 +const struct read_write_regs *get_bug_regs(u32 *iterations);
  #endif
index 438f128326a67a6c5237df32a0f392efdabee1c7,0649a4636de5b1b4fce619dd18095bcce164deed..5fb6506f4ead0b1ac44bb0ec18620419e1813b55
@@@ -17,14 -17,9 +17,18 @@@ struct arch_global_data 
  #if defined(CONFIG_FSL_ESDHC)
        u32 sdhc_clk;
  #endif
 +
 +#if defined(CONFIG_U_QE)
 +      u32 qe_clk;
 +      u32 brg_clk;
 +      uint mp_alloc_base;
 +      uint mp_alloc_top;
 +#endif /* CONFIG_U_QE */
 +
+ #ifdef CONFIG_VIDEO_IPUV3
+       unsigned int    ipu_hw_rev;
+ #endif
++
  #ifdef CONFIG_AT91FAMILY
        /* "static data" needed by at91's clock.c */
        unsigned long   cpu_clk_rate_hz;
@@@ -40,6 -35,9 +44,6 @@@
        unsigned long tbl;
        unsigned long lastinc;
        unsigned long long timer_reset_value;
 -#ifdef CONFIG_IXP425
 -      unsigned long timestamp;
 -#endif
  #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
        unsigned long tlb_addr;
        unsigned long tlb_size;
  
  #include <asm-generic/global_data.h>
  
 -#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
 +#ifdef __clang__
 +
 +#define DECLARE_GLOBAL_DATA_PTR
 +#define gd    get_gd()
 +
 +static inline gd_t *get_gd(void)
 +{
 +      gd_t *gd_ptr;
 +
 +#ifdef CONFIG_ARM64
 +      /*
 +       * Make will already error that reserving x18 is not supported at the
 +       * time of writing, clang: error: unknown argument: '-ffixed-x18'
 +       */
 +      __asm__ volatile("mov %0, x18\n" : "=r" (gd_ptr));
 +#else
 +      __asm__ volatile("mov %0, r9\n" : "=r" (gd_ptr));
 +#endif
 +
 +      return gd_ptr;
 +}
 +
 +#else
 +
 +#ifdef CONFIG_ARM64
 +#define DECLARE_GLOBAL_DATA_PTR               register volatile gd_t *gd asm ("x18")
 +#else
 +#define DECLARE_GLOBAL_DATA_PTR               register volatile gd_t *gd asm ("r9")
 +#endif
 +#endif
  
  #endif /* __ASM_GBL_DATA_H */
index d5c1f7f255a3c5f6eee70634d6dd747ac5639530,14a0c12ddcec1f0110fb331938bc4ac8417f3a06..8f9a11a288264e27d35244367f49991f06ff8bee
@@@ -150,17 -150,18 +150,20 @@@ struct mxs_dma_chan 
        unsigned int pending_num;
        struct list_head active;
        struct list_head done;
+       unsigned long timeout;
  };
  
  struct mxs_dma_desc *mxs_dma_desc_alloc(void);
  void mxs_dma_desc_free(struct mxs_dma_desc *);
  int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
+ int mxs_dma_set_timeout(int channel, unsigned long timeout);
+ unsigned long mxs_dma_get_timeout(int channel);
  
  int mxs_dma_go(int chan);
  void mxs_dma_init(void);
  int mxs_dma_init_channel(int chan);
  int mxs_dma_release(int chan);
  
 +void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc);
 +
  #endif        /* __DMA_H__ */
index e0a49be4ff79de66abdb22e420a94b354a83e89f,af4f835405466a59bd09ca6660087d61fed59ef3..9ba5f6be9622ffe68d0d1c5b7add81e66ca752d6
@@@ -8,8 -8,8 +8,8 @@@
   * SPDX-License-Identifier:   GPL-2.0+
   */
  
- #ifndef __MACH_IOMUX_V3_H__
- #define __MACH_IOMUX_V3_H__
+ #ifndef __ASM_ARCH_IOMUX_V3_H__
+ #define __ASM_ARCH_IOMUX_V3_H__
  
  #include <common.h>
  
   *
   * IOMUX/PAD Bit field definitions
   *
-  * MUX_CTRL_OFS:          0..11 (12)
-  * PAD_CTRL_OFS:         12..23 (12)
-  * SEL_INPUT_OFS:        24..35 (12)
-  * MUX_MODE + SION:      36..40  (5)
-  * PAD_CTRL + NO_PAD_CTRL: 41..58 (18)
-  * SEL_INP:              59..62  (4)
-  * reserved:               63    (1)
+  * MUX_CTRL_OFS:               0..11 (12)
+  * PAD_CTRL_OFS:              12..23 (12)
+  * SEL_INPUT_OFS:             24..35 (12)
+  * MUX_MODE + SION:           36..40  (5)
+  * PAD_CTRL + PAD_CTRL_VALID: 41..58 (18)
+  * SEL_INP:                   59..62  (4)
+  * reserved:                    63    (1)
  */
  
  typedef u64 iomux_v3_cfg_t;
  #define MUX_MODE_SHIFT                36
  #define MUX_MODE_MASK         ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT)
  #define MUX_PAD_CTRL_SHIFT    41
- #define MUX_PAD_CTRL_MASK     ((iomux_v3_cfg_t)0x3ffff << MUX_PAD_CTRL_SHIFT)
+ #define MUX_PAD_CTRL_MASK     ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT)
  #define MUX_SEL_INPUT_SHIFT   59
  #define MUX_SEL_INPUT_MASK    ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT)
  
- #define MUX_PAD_CTRL(x)               ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
 +#define MUX_MODE_SION         ((iomux_v3_cfg_t)IOMUX_CONFIG_SION << \
 +      MUX_MODE_SHIFT)
+ #define __MUX_PAD_CTRL(x)     ((x) | __PAD_CTRL_VALID)
+ #define MUX_PAD_CTRL(x)               (((iomux_v3_cfg_t)__MUX_PAD_CTRL(x) << \
+                                               MUX_PAD_CTRL_SHIFT))
  
  #define IOMUX_PAD(pad_ctrl_ofs, mux_ctrl_ofs, mux_mode, sel_input_ofs,        \
                sel_input, pad_ctrl)                                    \
  #define NO_MUX_I              0
  #define NO_PAD_I              0
  
- #define NO_PAD_CTRL           (1 << 17)
+ #define NO_MUX_I              0
+ #define NO_PAD_I              0
+ #define NO_PAD_CTRL           0
+ #define __PAD_CTRL_VALID      (1 << 17)
+ #define PAD_CTRL_VALID                ((iomux_v3_cfg_t)__PAD_CTRL_VALID << MUX_PAD_CTRL_SHIFT)
  
  #ifdef CONFIG_MX6
  
- #define PAD_CTL_HYS           (1 << 16)
+ #define PAD_CTL_HYS           __MUX_PAD_CTRL(1 << 16)
  
- #define PAD_CTL_PUS_100K_DOWN (0 << 14 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_47K_UP    (1 << 14 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_100K_UP   (2 << 14 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_22K_UP    (3 << 14 | PAD_CTL_PUE)
- #define PAD_CTL_PUE           (1 << 13 | PAD_CTL_PKE)
- #define PAD_CTL_PKE           (1 << 12)
+ #define PAD_CTL_PUS_100K_DOWN __MUX_PAD_CTRL(0 << 14 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_47K_UP    __MUX_PAD_CTRL(1 << 14 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_100K_UP   __MUX_PAD_CTRL(2 << 14 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_22K_UP    __MUX_PAD_CTRL(3 << 14 | PAD_CTL_PUE)
+ #define PAD_CTL_PUE           __MUX_PAD_CTRL(1 << 13 | PAD_CTL_PKE)
+ #define PAD_CTL_PKE           __MUX_PAD_CTRL(1 << 12)
  
- #define PAD_CTL_ODE           (1 << 11)
+ #define PAD_CTL_ODE           __MUX_PAD_CTRL(1 << 11)
  
- #define PAD_CTL_SPEED_LOW     (1 << 6)
- #define PAD_CTL_SPEED_MED     (2 << 6)
- #define PAD_CTL_SPEED_HIGH    (3 << 6)
+ #define PAD_CTL_SPEED_LOW     __MUX_PAD_CTRL(1 << 6)
+ #define PAD_CTL_SPEED_MED     __MUX_PAD_CTRL(2 << 6)
+ #define PAD_CTL_SPEED_HIGH    __MUX_PAD_CTRL(3 << 6)
  
- #define PAD_CTL_DSE_DISABLE   (0 << 3)
- #define PAD_CTL_DSE_240ohm    (1 << 3)
- #define PAD_CTL_DSE_120ohm    (2 << 3)
- #define PAD_CTL_DSE_80ohm     (3 << 3)
- #define PAD_CTL_DSE_60ohm     (4 << 3)
- #define PAD_CTL_DSE_48ohm     (5 << 3)
- #define PAD_CTL_DSE_40ohm     (6 << 3)
- #define PAD_CTL_DSE_34ohm     (7 << 3)
+ #define PAD_CTL_DSE_DISABLE   __MUX_PAD_CTRL(0 << 3)
+ #define PAD_CTL_DSE_240ohm    __MUX_PAD_CTRL(1 << 3)
+ #define PAD_CTL_DSE_120ohm    __MUX_PAD_CTRL(2 << 3)
+ #define PAD_CTL_DSE_80ohm     __MUX_PAD_CTRL(3 << 3)
+ #define PAD_CTL_DSE_60ohm     __MUX_PAD_CTRL(4 << 3)
+ #define PAD_CTL_DSE_48ohm     __MUX_PAD_CTRL(5 << 3)
+ #define PAD_CTL_DSE_40ohm     __MUX_PAD_CTRL(6 << 3)
+ #define PAD_CTL_DSE_34ohm     __MUX_PAD_CTRL(7 << 3)
  
- #define PAD_CTL_LVE           (1 << 1)
- #define PAD_CTL_LVE_BIT               (1 << 22)
 +#if defined CONFIG_MX6SL
++#define PAD_CTL_LVE           __MUX_PAD_CTRL(1 << 1)
++#define PAD_CTL_LVE_BIT               __MUX_PAD_CTRL(1 << 22)
 +#endif
 +
  #elif defined(CONFIG_VF610)
  
  #define PAD_MUX_MODE_SHIFT    20
  
- #define PAD_CTL_INPUT_DIFFERENTIAL (1 << 16)
++#define PAD_CTL_INPUT_DIFFERENTIAL __MUX_PAD_CTRL(1 << 16)
 +
- #define PAD_CTL_SPEED_MED     (1 << 12)
- #define PAD_CTL_SPEED_HIGH    (3 << 12)
+ #define PAD_CTL_SPEED_MED     __MUX_PAD_CTRL(1 << 12)
+ #define PAD_CTL_SPEED_HIGH    __MUX_PAD_CTRL(3 << 12)
  
- #define PAD_CTL_SRE           (1 << 11)
++#define PAD_CTL_SRE           __MUX_PAD_CTRL(1 << 11)
 +
- #define PAD_CTL_DSE_150ohm    (1 << 6)
- #define PAD_CTL_DSE_50ohm     (3 << 6)
- #define PAD_CTL_DSE_25ohm     (6 << 6)
- #define PAD_CTL_DSE_20ohm     (7 << 6)
++#define PAD_CTL_DSE_150ohm    __MUX_PAD_CTRL(1 << 6)
+ #define PAD_CTL_DSE_50ohm     __MUX_PAD_CTRL(3 << 6)
+ #define PAD_CTL_DSE_25ohm     __MUX_PAD_CTRL(6 << 6)
+ #define PAD_CTL_DSE_20ohm     __MUX_PAD_CTRL(7 << 6)
  
- #define PAD_CTL_PUS_47K_UP    (1 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_100K_UP   (2 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_22K_UP    (3 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PKE           (1 << 3)
- #define PAD_CTL_PUE           (1 << 2 | PAD_CTL_PKE)
+ #define PAD_CTL_PUS_47K_UP    __MUX_PAD_CTRL(1 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_100K_UP   __MUX_PAD_CTRL(2 << 4 | PAD_CTL_PUE)
++#define PAD_CTL_PUS_22K_UP    __MUX_PAD_CTRL(3 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PKE           __MUX_PAD_CTRL(1 << 3)
+ #define PAD_CTL_PUE           __MUX_PAD_CTRL(1 << 2 | PAD_CTL_PKE)
  
- #define PAD_CTL_OBE_IBE_ENABLE        (3 << 0)
- #define PAD_CTL_OBE_ENABLE    (1 << 1)
- #define PAD_CTL_IBE_ENABLE    (1 << 0)
+ #define PAD_CTL_OBE_IBE_ENABLE        __MUX_PAD_CTRL(3 << 0)
++#define PAD_CTL_OBE_ENABLE    __MUX_PAD_CTRL(1 << 1)
++#define PAD_CTL_IBE_ENABLE    __MUX_PAD_CTRL(1 << 0)
  
  #else
  
- #define PAD_CTL_DVS           (1 << 13)
- #define PAD_CTL_INPUT_DDR     (1 << 9)
- #define PAD_CTL_HYS           (1 << 8)
+ #define PAD_CTL_DVS           __MUX_PAD_CTRL(1 << 13)
+ #define PAD_CTL_INPUT_DDR     __MUX_PAD_CTRL(1 << 9)
+ #define PAD_CTL_HYS           __MUX_PAD_CTRL(1 << 8)
  
- #define PAD_CTL_PKE           (1 << 7)
- #define PAD_CTL_PUE           (1 << 6 | PAD_CTL_PKE)
- #define PAD_CTL_PUS_100K_DOWN (0 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_47K_UP    (1 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_100K_UP   (2 << 4 | PAD_CTL_PUE)
- #define PAD_CTL_PUS_22K_UP    (3 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PKE           __MUX_PAD_CTRL(1 << 7)
+ #define PAD_CTL_PUE           __MUX_PAD_CTRL(1 << 6 | PAD_CTL_PKE)
+ #define PAD_CTL_PUS_100K_DOWN __MUX_PAD_CTRL(0 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_47K_UP    __MUX_PAD_CTRL(1 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_100K_UP   __MUX_PAD_CTRL(2 << 4 | PAD_CTL_PUE)
+ #define PAD_CTL_PUS_22K_UP    __MUX_PAD_CTRL(3 << 4 | PAD_CTL_PUE)
  
- #define PAD_CTL_ODE           (1 << 3)
+ #define PAD_CTL_ODE           __MUX_PAD_CTRL(1 << 3)
  
- #define PAD_CTL_DSE_LOW               (0 << 1)
- #define PAD_CTL_DSE_MED               (1 << 1)
- #define PAD_CTL_DSE_HIGH      (2 << 1)
- #define PAD_CTL_DSE_MAX               (3 << 1)
+ #define PAD_CTL_DSE_LOW               __MUX_PAD_CTRL(0 << 1)
+ #define PAD_CTL_DSE_MED               __MUX_PAD_CTRL(1 << 1)
+ #define PAD_CTL_DSE_HIGH      __MUX_PAD_CTRL(2 << 1)
+ #define PAD_CTL_DSE_MAX               __MUX_PAD_CTRL(3 << 1)
  
  #endif
  
- #define PAD_CTL_SRE_SLOW      (0 << 0)
- #define PAD_CTL_SRE_FAST      (1 << 0)
+ #define PAD_CTL_SRE_SLOW      __MUX_PAD_CTRL(0 << 0)
+ #define PAD_CTL_SRE_FAST      __MUX_PAD_CTRL(1 << 0)
  
  #define IOMUX_CONFIG_SION     0x10
  
  #define GPIO_PORTE            (4 << GPIO_PORT_SHIFT)
  #define GPIO_PORTF            (5 << GPIO_PORT_SHIFT)
  
--void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
++void imx_iomux_v3_setup_pad(const iomux_v3_cfg_t const pad);
  void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
                                     unsigned count);
 +/*
 +* Set bits for general purpose registers
 +*/
 +void imx_iomux_set_gpr_register(int group, int start_bit,
 +                                       int num_bits, int value);
 +
 +/* macros for declaring and using pinmux array */
 +#if defined(CONFIG_MX6QDL)
 +#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)
 +#define SETUP_IOMUX_PAD(def)                                  \
 +if (is_cpu_type(MXC_CPU_MX6Q)) {                              \
 +      imx_iomux_v3_setup_pad(MX6Q_##def);                     \
 +} else {                                                      \
 +      imx_iomux_v3_setup_pad(MX6DL_##def);                    \
 +}
 +#define SETUP_IOMUX_PADS(x)                                   \
 +      imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x)/2)
 +#elif defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
 +#define IOMUX_PADS(x) MX6Q_##x
 +#define SETUP_IOMUX_PAD(def)                                  \
 +      imx_iomux_v3_setup_pad(MX6Q_##def);
 +#define SETUP_IOMUX_PADS(x)                                   \
 +      imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x))
 +#else
 +#define IOMUX_PADS(x) MX6DL_##x
 +#define SETUP_IOMUX_PAD(def)                                  \
 +      imx_iomux_v3_setup_pad(MX6DL_##def);
 +#define SETUP_IOMUX_PADS(x)                                   \
 +      imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x))
 +#endif
  
- #endif        /* __MACH_IOMUX_V3_H__*/
+ #endif        /* __ASM_ARCH_IOMUX_V3_H__*/
index 89f22946895301b09a183ead75503ae4dff0f1b2,8b5b9f47b465bb047f632d9da1a6f71457bd0d54..f5096dc0fda8fe255bfb0407fcf21c06df20e078
@@@ -1,89 -1,6 +1,89 @@@
  #ifndef __ASM_ARM_SYSTEM_H
  #define __ASM_ARM_SYSTEM_H
  
 +#ifdef CONFIG_ARM64
 +
 +/*
 + * SCTLR_EL1/SCTLR_EL2/SCTLR_EL3 bits definitions
 + */
 +#define CR_M          (1 << 0)        /* MMU enable                   */
 +#define CR_A          (1 << 1)        /* Alignment abort enable       */
 +#define CR_C          (1 << 2)        /* Dcache enable                */
 +#define CR_SA         (1 << 3)        /* Stack Alignment Check Enable */
 +#define CR_I          (1 << 12)       /* Icache enable                */
 +#define CR_WXN                (1 << 19)       /* Write Permision Imply XN     */
 +#define CR_EE         (1 << 25)       /* Exception (Big) Endian       */
 +
 +#define PGTABLE_SIZE  (0x10000)
 +
 +#ifndef __ASSEMBLY__
 +
 +#define isb()                         \
 +      ({asm volatile(                 \
 +      "isb" : : : "memory");          \
 +      })
 +
 +#define wfi()                         \
 +      ({asm volatile(                 \
 +      "wfi" : : : "memory");          \
 +      })
 +
 +static inline unsigned int current_el(void)
 +{
 +      unsigned int el;
 +      asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc");
 +      return el >> 2;
 +}
 +
 +static inline unsigned int get_sctlr(void)
 +{
 +      unsigned int el, val;
 +
 +      el = current_el();
 +      if (el == 1)
 +              asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
 +      else if (el == 2)
 +              asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc");
 +      else
 +              asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc");
 +
 +      return val;
 +}
 +
 +static inline void set_sctlr(unsigned int val)
 +{
 +      unsigned int el;
 +
 +      el = current_el();
 +      if (el == 1)
 +              asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc");
 +      else if (el == 2)
 +              asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc");
 +      else
 +              asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc");
 +
 +      asm volatile("isb");
 +}
 +
 +void __asm_flush_dcache_all(void);
 +void __asm_invalidate_dcache_all(void);
 +void __asm_flush_dcache_range(u64 start, u64 end);
 +void __asm_invalidate_tlb_all(void);
 +void __asm_invalidate_icache_all(void);
 +
 +void armv8_switch_to_el2(void);
 +void armv8_switch_to_el1(void);
 +void gic_init(void);
 +void gic_send_sgi(unsigned long sgino);
 +void wait_for_wakeup(void);
 +void smp_kick_all_cpus(void);
 +
 +void flush_l3_cache(void);
 +
 +#endif        /* __ASSEMBLY__ */
 +
 +#else /* CONFIG_ARM64 */
 +
  #ifdef __KERNEL__
  
  #define CPU_ARCH_UNKNOWN      0
  #define CR_AFE        (1 << 29)       /* Access flag enable                   */
  #define CR_TE (1 << 30)       /* Thumb exception enable               */
  
 +#define PGTABLE_SIZE          (4096 * 4)
 +
  /*
   * This is used to ensure the compiler did actually allocate the register we
   * asked it for some inline assembly sequences.  Apparently we can't trust
  static inline unsigned int get_cr(void)
  {
        unsigned int val;
-       asm("mrc p15, 0, %0, c1, c0, 0  @ get CR" : "=r" (val) : : "cc");
+       asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
        return val;
  }
  
@@@ -185,7 -100,6 +185,7 @@@ enum dcache_option 
        DCACHE_OFF = 0x12,
        DCACHE_WRITETHROUGH = 0x1a,
        DCACHE_WRITEBACK = 0x1e,
 +      DCACHE_WRITEALLOC = 0x16,
  };
  
  /* Size of an MMU section */
@@@ -201,7 -115,7 +201,7 @@@ enum 
   * \param size                size of memory region to change
   * \param option      dcache option to select
   */
 -void mmu_set_region_dcache_behaviour(u32 start, int size,
 +void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
                                     enum dcache_option option);
  
  /**
   */
  void mmu_page_table_flush(unsigned long start, unsigned long stop);
  
 +#ifdef CONFIG_SYS_NONCACHED_MEMORY
 +void noncached_init(void);
 +phys_addr_t noncached_alloc(size_t size, size_t align);
 +#endif /* CONFIG_SYS_NONCACHED_MEMORY */
 +
  #endif /* __ASSEMBLY__ */
  
  #define arch_align_stack(x) (x)
  
  #endif /* __KERNEL__ */
  
 +#endif /* CONFIG_ARM64 */
 +
  #endif
index b0c26e5d689318195343152926eac50699cdd3d7,0000000000000000000000000000000000000000..faafc627cd907d22bb9b805010964d9198e32815
mode 100644,000000..100644
--- /dev/null
@@@ -1,248 -1,0 +1,288 @@@
-       || defined(CONFIG_MX51) || defined(CONFIG_MX53)
 +/*
 + * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
 + *
 + * This program is used to generate definitions needed by
 + * assembly language modules.
 + *
 + * We use the technique used in the OSF Mach kernel code:
 + * generate asm statements containing #defines,
 + * compile this file to assembler, and then extract the
 + * #defines from the assembly-language output.
 + *
 + * SPDX-License-Identifier:   GPL-2.0+
 + */
 +
 +#include <common.h>
 +#include <linux/kbuild.h>
 +
 +#if defined(CONFIG_MB86R0x)
 +#include <asm/arch/mb86r0x.h>
 +#endif
 +#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) \
++      || defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
 +#include <asm/arch/imx-regs.h>
 +#endif
++#if defined(CONFIG_MX6)
++#include <asm/arch/crm_regs.h>
++#endif
 +
 +int main(void)
 +{
 +      /*
 +       * TODO : Check if each entry in this file is really necessary.
 +       *   - struct mb86r0x_ddr2
 +       *   - struct mb86r0x_memc
 +       *   - struct esdramc_regs
 +       *   - struct max_regs
 +       *   - struct aips_regs
 +       *   - struct aipi_regs
 +       *   - struct clkctl
 +       *   - struct dpll
 +       * are used only for generating asm-offsets.h.
 +       * It means their offset addresses are referenced only from assembly
 +       * code. Is it better to define the macros directly in headers?
 +       */
 +
 +#if defined(CONFIG_MB86R0x)
 +      /* ddr2 controller */
 +      DEFINE(DDR2_DRIC, offsetof(struct mb86r0x_ddr2c, dric));
 +      DEFINE(DDR2_DRIC1, offsetof(struct mb86r0x_ddr2c, dric1));
 +      DEFINE(DDR2_DRIC2, offsetof(struct mb86r0x_ddr2c, dric2));
 +      DEFINE(DDR2_DRCA, offsetof(struct mb86r0x_ddr2c, drca));
 +      DEFINE(DDR2_DRCM, offsetof(struct mb86r0x_ddr2c, drcm));
 +      DEFINE(DDR2_DRCST1, offsetof(struct mb86r0x_ddr2c, drcst1));
 +      DEFINE(DDR2_DRCST2, offsetof(struct mb86r0x_ddr2c, drcst2));
 +      DEFINE(DDR2_DRCR, offsetof(struct mb86r0x_ddr2c, drcr));
 +      DEFINE(DDR2_DRCF, offsetof(struct mb86r0x_ddr2c, drcf));
 +      DEFINE(DDR2_DRASR, offsetof(struct mb86r0x_ddr2c, drasr));
 +      DEFINE(DDR2_DRIMS, offsetof(struct mb86r0x_ddr2c, drims));
 +      DEFINE(DDR2_DROS, offsetof(struct mb86r0x_ddr2c, dros));
 +      DEFINE(DDR2_DRIBSODT1, offsetof(struct mb86r0x_ddr2c, dribsodt1));
 +      DEFINE(DDR2_DROABA, offsetof(struct mb86r0x_ddr2c, droaba));
 +      DEFINE(DDR2_DROBS, offsetof(struct mb86r0x_ddr2c, drobs));
 +
 +      /* clock reset generator */
 +      DEFINE(CRG_CRPR, offsetof(struct mb86r0x_crg, crpr));
 +      DEFINE(CRG_CRHA, offsetof(struct mb86r0x_crg, crha));
 +      DEFINE(CRG_CRPA, offsetof(struct mb86r0x_crg, crpa));
 +      DEFINE(CRG_CRPB, offsetof(struct mb86r0x_crg, crpb));
 +      DEFINE(CRG_CRHB, offsetof(struct mb86r0x_crg, crhb));
 +      DEFINE(CRG_CRAM, offsetof(struct mb86r0x_crg, cram));
 +
 +      /* chip control module */
 +      DEFINE(CCNT_CDCRC, offsetof(struct mb86r0x_ccnt, cdcrc));
 +
 +      /* external bus interface */
 +      DEFINE(MEMC_MCFMODE0, offsetof(struct mb86r0x_memc, mcfmode[0]));
 +      DEFINE(MEMC_MCFMODE2, offsetof(struct mb86r0x_memc, mcfmode[2]));
 +      DEFINE(MEMC_MCFMODE4, offsetof(struct mb86r0x_memc, mcfmode[4]));
 +      DEFINE(MEMC_MCFTIM0, offsetof(struct mb86r0x_memc, mcftim[0]));
 +      DEFINE(MEMC_MCFTIM2, offsetof(struct mb86r0x_memc, mcftim[2]));
 +      DEFINE(MEMC_MCFTIM4, offsetof(struct mb86r0x_memc, mcftim[4]));
 +      DEFINE(MEMC_MCFAREA0, offsetof(struct mb86r0x_memc, mcfarea[0]));
 +      DEFINE(MEMC_MCFAREA2, offsetof(struct mb86r0x_memc, mcfarea[2]));
 +      DEFINE(MEMC_MCFAREA4, offsetof(struct mb86r0x_memc, mcfarea[4]));
 +#endif
 +
 +#if defined(CONFIG_MX25)
 +      /* Clock Control Module */
 +      DEFINE(CCM_CCTL, offsetof(struct ccm_regs, cctl));
 +      DEFINE(CCM_CGCR0, offsetof(struct ccm_regs, cgr0));
 +      DEFINE(CCM_CGCR1, offsetof(struct ccm_regs, cgr1));
 +      DEFINE(CCM_CGCR2, offsetof(struct ccm_regs, cgr2));
 +      DEFINE(CCM_PCDR2, offsetof(struct ccm_regs, pcdr[2]));
 +      DEFINE(CCM_MCR, offsetof(struct ccm_regs, mcr));
 +
 +      /* Enhanced SDRAM Controller */
 +      DEFINE(ESDRAMC_ESDCTL0, offsetof(struct esdramc_regs, ctl0));
 +      DEFINE(ESDRAMC_ESDCFG0, offsetof(struct esdramc_regs, cfg0));
 +      DEFINE(ESDRAMC_ESDMISC, offsetof(struct esdramc_regs, misc));
 +
 +      /* Multi-Layer AHB Crossbar Switch */
 +      DEFINE(MAX_MPR0, offsetof(struct max_regs, mpr0));
 +      DEFINE(MAX_SGPCR0, offsetof(struct max_regs, sgpcr0));
 +      DEFINE(MAX_MPR1, offsetof(struct max_regs, mpr1));
 +      DEFINE(MAX_SGPCR1, offsetof(struct max_regs, sgpcr1));
 +      DEFINE(MAX_MPR2, offsetof(struct max_regs, mpr2));
 +      DEFINE(MAX_SGPCR2, offsetof(struct max_regs, sgpcr2));
 +      DEFINE(MAX_MPR3, offsetof(struct max_regs, mpr3));
 +      DEFINE(MAX_SGPCR3, offsetof(struct max_regs, sgpcr3));
 +      DEFINE(MAX_MPR4, offsetof(struct max_regs, mpr4));
 +      DEFINE(MAX_SGPCR4, offsetof(struct max_regs, sgpcr4));
 +      DEFINE(MAX_MGPCR0, offsetof(struct max_regs, mgpcr0));
 +      DEFINE(MAX_MGPCR1, offsetof(struct max_regs, mgpcr1));
 +      DEFINE(MAX_MGPCR2, offsetof(struct max_regs, mgpcr2));
 +      DEFINE(MAX_MGPCR3, offsetof(struct max_regs, mgpcr3));
 +      DEFINE(MAX_MGPCR4, offsetof(struct max_regs, mgpcr4));
 +
 +      /* AHB <-> IP-Bus Interface */
 +      DEFINE(AIPS_MPR_0_7, offsetof(struct aips_regs, mpr_0_7));
 +      DEFINE(AIPS_MPR_8_15, offsetof(struct aips_regs, mpr_8_15));
 +#endif
 +
 +#if defined(CONFIG_MX27)
 +      DEFINE(AIPI1_PSR0, IMX_AIPI1_BASE + offsetof(struct aipi_regs, psr0));
 +      DEFINE(AIPI1_PSR1, IMX_AIPI1_BASE + offsetof(struct aipi_regs, psr1));
 +      DEFINE(AIPI2_PSR0, IMX_AIPI2_BASE + offsetof(struct aipi_regs, psr0));
 +      DEFINE(AIPI2_PSR1, IMX_AIPI2_BASE + offsetof(struct aipi_regs, psr1));
 +
 +      DEFINE(CSCR, IMX_PLL_BASE + offsetof(struct pll_regs, cscr));
 +      DEFINE(MPCTL0, IMX_PLL_BASE + offsetof(struct pll_regs, mpctl0));
 +      DEFINE(SPCTL0, IMX_PLL_BASE + offsetof(struct pll_regs, spctl0));
 +      DEFINE(PCDR0, IMX_PLL_BASE + offsetof(struct pll_regs, pcdr0));
 +      DEFINE(PCDR1, IMX_PLL_BASE + offsetof(struct pll_regs, pcdr1));
 +      DEFINE(PCCR0, IMX_PLL_BASE + offsetof(struct pll_regs, pccr0));
 +      DEFINE(PCCR1, IMX_PLL_BASE + offsetof(struct pll_regs, pccr1));
 +
 +      DEFINE(ESDCTL0_ROF, offsetof(struct esdramc_regs, esdctl0));
 +      DEFINE(ESDCFG0_ROF, offsetof(struct esdramc_regs, esdcfg0));
 +      DEFINE(ESDCTL1_ROF, offsetof(struct esdramc_regs, esdctl1));
 +      DEFINE(ESDCFG1_ROF, offsetof(struct esdramc_regs, esdcfg1));
 +      DEFINE(ESDMISC_ROF, offsetof(struct esdramc_regs, esdmisc));
 +
 +      DEFINE(GPCR, IMX_SYSTEM_CTL_BASE +
 +              offsetof(struct system_control_regs, gpcr));
 +      DEFINE(FMCR, IMX_SYSTEM_CTL_BASE +
 +              offsetof(struct system_control_regs, fmcr));
 +#endif
 +
 +#if defined(CONFIG_MX35)
 +      /* Round up to make sure size gives nice stack alignment */
 +      DEFINE(CLKCTL_CCMR, offsetof(struct ccm_regs, ccmr));
 +      DEFINE(CLKCTL_PDR0, offsetof(struct ccm_regs, pdr0));
 +      DEFINE(CLKCTL_PDR1, offsetof(struct ccm_regs, pdr1));
 +      DEFINE(CLKCTL_PDR2, offsetof(struct ccm_regs, pdr2));
 +      DEFINE(CLKCTL_PDR3, offsetof(struct ccm_regs, pdr3));
 +      DEFINE(CLKCTL_PDR4, offsetof(struct ccm_regs, pdr4));
 +      DEFINE(CLKCTL_RCSR, offsetof(struct ccm_regs, rcsr));
 +      DEFINE(CLKCTL_MPCTL, offsetof(struct ccm_regs, mpctl));
 +      DEFINE(CLKCTL_PPCTL, offsetof(struct ccm_regs, ppctl));
 +      DEFINE(CLKCTL_ACMR, offsetof(struct ccm_regs, acmr));
 +      DEFINE(CLKCTL_COSR, offsetof(struct ccm_regs, cosr));
 +      DEFINE(CLKCTL_CGR0, offsetof(struct ccm_regs, cgr0));
 +      DEFINE(CLKCTL_CGR1, offsetof(struct ccm_regs, cgr1));
 +      DEFINE(CLKCTL_CGR2, offsetof(struct ccm_regs, cgr2));
 +      DEFINE(CLKCTL_CGR3, offsetof(struct ccm_regs, cgr3));
 +
 +      /* Multi-Layer AHB Crossbar Switch */
 +      DEFINE(MAX_MPR0, offsetof(struct max_regs, mpr0));
 +      DEFINE(MAX_SGPCR0, offsetof(struct max_regs, sgpcr0));
 +      DEFINE(MAX_MPR1, offsetof(struct max_regs, mpr1));
 +      DEFINE(MAX_SGPCR1, offsetof(struct max_regs, sgpcr1));
 +      DEFINE(MAX_MPR2, offsetof(struct max_regs, mpr2));
 +      DEFINE(MAX_SGPCR2, offsetof(struct max_regs, sgpcr2));
 +      DEFINE(MAX_MPR3, offsetof(struct max_regs, mpr3));
 +      DEFINE(MAX_SGPCR3, offsetof(struct max_regs, sgpcr3));
 +      DEFINE(MAX_MPR4, offsetof(struct max_regs, mpr4));
 +      DEFINE(MAX_SGPCR4, offsetof(struct max_regs, sgpcr4));
 +      DEFINE(MAX_MGPCR0, offsetof(struct max_regs, mgpcr0));
 +      DEFINE(MAX_MGPCR1, offsetof(struct max_regs, mgpcr1));
 +      DEFINE(MAX_MGPCR2, offsetof(struct max_regs, mgpcr2));
 +      DEFINE(MAX_MGPCR3, offsetof(struct max_regs, mgpcr3));
 +      DEFINE(MAX_MGPCR4, offsetof(struct max_regs, mgpcr4));
 +      DEFINE(MAX_MGPCR5, offsetof(struct max_regs, mgpcr5));
 +
 +      /* AHB <-> IP-Bus Interface */
 +      DEFINE(AIPS_MPR_0_7, offsetof(struct aips_regs, mpr_0_7));
 +      DEFINE(AIPS_MPR_8_15, offsetof(struct aips_regs, mpr_8_15));
 +      DEFINE(AIPS_PACR_0_7, offsetof(struct aips_regs, pacr_0_7));
 +      DEFINE(AIPS_PACR_8_15, offsetof(struct aips_regs, pacr_8_15));
 +      DEFINE(AIPS_PACR_16_23, offsetof(struct aips_regs, pacr_16_23));
 +      DEFINE(AIPS_PACR_24_31, offsetof(struct aips_regs, pacr_24_31));
 +      DEFINE(AIPS_OPACR_0_7, offsetof(struct aips_regs, opacr_0_7));
 +      DEFINE(AIPS_OPACR_8_15, offsetof(struct aips_regs, opacr_8_15));
 +      DEFINE(AIPS_OPACR_16_23, offsetof(struct aips_regs, opacr_16_23));
 +      DEFINE(AIPS_OPACR_24_31, offsetof(struct aips_regs, opacr_24_31));
 +      DEFINE(AIPS_OPACR_32_39, offsetof(struct aips_regs, opacr_32_39));
 +#endif
 +
 +#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
 +      /* Round up to make sure size gives nice stack alignment */
 +      DEFINE(CLKCTL_CCMR, offsetof(struct clkctl, ccr));
 +      DEFINE(CLKCTL_CCDR, offsetof(struct clkctl, ccdr));
 +      DEFINE(CLKCTL_CSR, offsetof(struct clkctl, csr));
 +      DEFINE(CLKCTL_CCSR, offsetof(struct clkctl, ccsr));
 +      DEFINE(CLKCTL_CACRR, offsetof(struct clkctl, cacrr));
 +      DEFINE(CLKCTL_CBCDR, offsetof(struct clkctl, cbcdr));
 +      DEFINE(CLKCTL_CBCMR, offsetof(struct clkctl, cbcmr));
 +      DEFINE(CLKCTL_CSCMR1, offsetof(struct clkctl, cscmr1));
 +      DEFINE(CLKCTL_CSCMR2, offsetof(struct clkctl, cscmr2));
 +      DEFINE(CLKCTL_CSCDR1, offsetof(struct clkctl, cscdr1));
 +      DEFINE(CLKCTL_CS1CDR, offsetof(struct clkctl, cs1cdr));
 +      DEFINE(CLKCTL_CS2CDR, offsetof(struct clkctl, cs2cdr));
 +      DEFINE(CLKCTL_CDCDR, offsetof(struct clkctl, cdcdr));
 +      DEFINE(CLKCTL_CHSCCDR, offsetof(struct clkctl, chsccdr));
 +      DEFINE(CLKCTL_CSCDR2, offsetof(struct clkctl, cscdr2));
 +      DEFINE(CLKCTL_CSCDR3, offsetof(struct clkctl, cscdr3));
 +      DEFINE(CLKCTL_CSCDR4, offsetof(struct clkctl, cscdr4));
 +      DEFINE(CLKCTL_CWDR, offsetof(struct clkctl, cwdr));
 +      DEFINE(CLKCTL_CDHIPR, offsetof(struct clkctl, cdhipr));
 +      DEFINE(CLKCTL_CDCR, offsetof(struct clkctl, cdcr));
 +      DEFINE(CLKCTL_CTOR, offsetof(struct clkctl, ctor));
 +      DEFINE(CLKCTL_CLPCR, offsetof(struct clkctl, clpcr));
 +      DEFINE(CLKCTL_CISR, offsetof(struct clkctl, cisr));
 +      DEFINE(CLKCTL_CIMR, offsetof(struct clkctl, cimr));
 +      DEFINE(CLKCTL_CCOSR, offsetof(struct clkctl, ccosr));
 +      DEFINE(CLKCTL_CGPR, offsetof(struct clkctl, cgpr));
 +      DEFINE(CLKCTL_CCGR0, offsetof(struct clkctl, ccgr0));
 +      DEFINE(CLKCTL_CCGR1, offsetof(struct clkctl, ccgr1));
 +      DEFINE(CLKCTL_CCGR2, offsetof(struct clkctl, ccgr2));
 +      DEFINE(CLKCTL_CCGR3, offsetof(struct clkctl, ccgr3));
 +      DEFINE(CLKCTL_CCGR4, offsetof(struct clkctl, ccgr4));
 +      DEFINE(CLKCTL_CCGR5, offsetof(struct clkctl, ccgr5));
 +      DEFINE(CLKCTL_CCGR6, offsetof(struct clkctl, ccgr6));
 +      DEFINE(CLKCTL_CMEOR, offsetof(struct clkctl, cmeor));
 +#if defined(CONFIG_MX53)
 +      DEFINE(CLKCTL_CCGR7, offsetof(struct clkctl, ccgr7));
 +#endif
 +
 +      /* DPLL */
 +      DEFINE(PLL_DP_CTL, offsetof(struct dpll, dp_ctl));
 +      DEFINE(PLL_DP_CONFIG, offsetof(struct dpll, dp_config));
 +      DEFINE(PLL_DP_OP, offsetof(struct dpll, dp_op));
 +      DEFINE(PLL_DP_MFD, offsetof(struct dpll, dp_mfd));
 +      DEFINE(PLL_DP_MFN, offsetof(struct dpll, dp_mfn));
 +      DEFINE(PLL_DP_HFS_OP, offsetof(struct dpll, dp_hfs_op));
 +      DEFINE(PLL_DP_HFS_MFD, offsetof(struct dpll, dp_hfs_mfd));
 +      DEFINE(PLL_DP_HFS_MFN, offsetof(struct dpll, dp_hfs_mfn));
 +#endif
++#if defined(CONFIG_MX6)
++      DEFINE(CCM_CCR, offsetof(struct mxc_ccm_reg, ccr));
++      DEFINE(CCM_CCDR, offsetof(struct mxc_ccm_reg, ccdr));
++      DEFINE(CCM_CSR, offsetof(struct mxc_ccm_reg, csr));
++      DEFINE(CCM_CCSR, offsetof(struct mxc_ccm_reg, ccsr));
++      DEFINE(CCM_CACRR, offsetof(struct mxc_ccm_reg, cacrr));
++      DEFINE(CCM_CBCDR, offsetof(struct mxc_ccm_reg, cbcdr));
++      DEFINE(CCM_CBCMR, offsetof(struct mxc_ccm_reg, cbcmr));
++      DEFINE(CCM_CSCMR1, offsetof(struct mxc_ccm_reg, cscmr1));
++      DEFINE(CCM_CSCMR2, offsetof(struct mxc_ccm_reg, cscmr2));
++      DEFINE(CCM_CSCDR1, offsetof(struct mxc_ccm_reg, cscdr1));
++      DEFINE(CCM_CS1CDR, offsetof(struct mxc_ccm_reg, cs1cdr));
++      DEFINE(CCM_CS2CDR, offsetof(struct mxc_ccm_reg, cs2cdr));
++      DEFINE(CCM_CDCDR, offsetof(struct mxc_ccm_reg, cdcdr));
++      DEFINE(CCM_CHSCCDR, offsetof(struct mxc_ccm_reg, chsccdr));
++      DEFINE(CCM_CSCDR2, offsetof(struct mxc_ccm_reg, cscdr2));
++      DEFINE(CCM_CSCDR3, offsetof(struct mxc_ccm_reg, cscdr3));
++      DEFINE(CCM_CSCDR4, offsetof(struct mxc_ccm_reg, cscdr4));
++      DEFINE(CCM_CDHIPR, offsetof(struct mxc_ccm_reg, cdhipr));
++      DEFINE(CCM_CDCR, offsetof(struct mxc_ccm_reg, cdcr));
++      DEFINE(CCM_CTOR, offsetof(struct mxc_ccm_reg, ctor));
++      DEFINE(CCM_CLPCR, offsetof(struct mxc_ccm_reg, clpcr));
++      DEFINE(CCM_CISR, offsetof(struct mxc_ccm_reg, cisr));
++      DEFINE(CCM_CIMR, offsetof(struct mxc_ccm_reg, cimr));
++      DEFINE(CCM_CCOSR, offsetof(struct mxc_ccm_reg, ccosr));
++      DEFINE(CCM_CGPR, offsetof(struct mxc_ccm_reg, cgpr));
++      DEFINE(CCM_CCGR0, offsetof(struct mxc_ccm_reg, CCGR0));
++      DEFINE(CCM_CCGR1, offsetof(struct mxc_ccm_reg, CCGR1));
++      DEFINE(CCM_CCGR2, offsetof(struct mxc_ccm_reg, CCGR2));
++      DEFINE(CCM_CCGR3, offsetof(struct mxc_ccm_reg, CCGR3));
++      DEFINE(CCM_CCGR4, offsetof(struct mxc_ccm_reg, CCGR4));
++      DEFINE(CCM_CCGR5, offsetof(struct mxc_ccm_reg, CCGR5));
++      DEFINE(CCM_CCGR6, offsetof(struct mxc_ccm_reg, CCGR6));
++      DEFINE(CCM_CCGR7, offsetof(struct mxc_ccm_reg, CCGR7));
++      DEFINE(CCM_CMEOR, offsetof(struct mxc_ccm_reg, cmeor));
 +
++      DEFINE(ANATOP_PLL_ENET, offsetof(struct anatop_regs, pll_enet));
++#endif
 +      return 0;
 +}
diff --combined arch/arm/lib/board.c
index f6062557e6677fe0636520f9d7f76a9eedfc8d50,ad78e7366761bca5615dce7e8cd7285c56c97bb0..3c0ba079d3d864c517040023e83eebf07ff170bb
@@@ -33,8 -33,6 +33,8 @@@
  #include <nand.h>
  #include <onenand_uboot.h>
  #include <mmc.h>
 +#include <scsi.h>
 +#include <status_led.h>
  #include <libfdt.h>
  #include <fdtdec.h>
  #include <post.h>
@@@ -64,15 -62,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) {}
  
  /*
   ************************************************************************
@@@ -97,8 -105,8 +97,8 @@@ static int display_banner(void
  {
        printf("\n\n%s\n\n", version_string);
        debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
 -             _TEXT_BASE,
 -             _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);
 +             (ulong)&_start,
 +             (ulong)&__bss_start, (ulong)&__bss_end);
  #ifdef CONFIG_MODEM_SUPPORT
        debug("Modem Support enabled\n");
  #endif
@@@ -189,21 -197,29 +189,21 @@@ static int arm_pci_init(void
   */
  typedef int (init_fnc_t) (void);
  
 -int print_cpuinfo(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)
@@@ -234,7 -250,9 +234,7 @@@ init_fnc_t *init_sequence[] = 
        serial_init,            /* serial communications setup */
        console_init_f,         /* stage 1 init of console */
        display_banner,         /* say that we are here */
 -#if defined(CONFIG_DISPLAY_CPUINFO)
        print_cpuinfo,          /* display cpu info (and speed) */
 -#endif
  #if defined(CONFIG_DISPLAY_BOARDINFO)
        checkboard,             /* display board info */
  #endif
@@@ -259,13 -277,13 +259,13 @@@ void board_init_f(ulong bootflag
  
        memset((void *)gd, 0, sizeof(gd_t));
  
 -      gd->mon_len = _bss_end_ofs;
 +      gd->mon_len = (ulong)&__bss_end - (ulong)_start;
  #ifdef CONFIG_OF_EMBED
        /* Get a pointer to the FDT */
 -      gd->fdt_blob = _binary_dt_dtb_start;
 +      gd->fdt_blob = __dtb_dt_begin;
  #elif defined CONFIG_OF_SEPARATE
        /* FDT is at end of image */
 -      gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
 +      gd->fdt_blob = &_end;
  #endif
        /* Allow the early environment to override the fdt address */
        gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
        gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
  #endif
  
 -      addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
 +      addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize();
  
  #ifdef CONFIG_LOGBUFFER
  #ifndef CONFIG_ALT_LB_ADDR
  
  #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
        /* reserve TLB table */
 -      gd->arch.tlb_size = 4096 * 4;
 +      gd->arch.tlb_size = PGTABLE_SIZE;
        addr -= gd->arch.tlb_size;
  
        /* round down to next 64 kB limit */
        }
  #endif
  
 +#ifndef CONFIG_ARM64
        /* setup stackpointer for exeptions */
        gd->irq_sp = addr_sp;
  #ifdef CONFIG_USE_IRQ
  
        /* 8-byte alignment for ABI compliance */
        addr_sp &= ~0x07;
 +#else /* CONFIG_ARM64 */
 +      /* 16-byte alignment for ABI compliance */
 +      addr_sp &= ~0x0f;
 +#endif        /* CONFIG_ARM64 */
  #else
        addr_sp += 128; /* leave 32 words for abort-stack   */
        gd->irq_sp = addr_sp;
        post_run(NULL, POST_ROM | post_bootmode_get(0));
  #endif
  
 -      gd->bd->bi_baudrate = gd->baudrate;
        /* Ram ist board specific, so move it to board code ... */
        dram_init_banksize();
        display_dram_config();  /* and display it */
  
        gd->relocaddr = addr;
        gd->start_addr_sp = addr_sp;
 -      gd->reloc_off = addr - _TEXT_BASE;
 -
 +      gd->reloc_off = addr - (ulong)&_start;
        debug("relocation Offset is: %08lx\n", gd->reloc_off);
        if (new_fdt) {
                memcpy(new_fdt, gd->fdt_blob, fdt_size);
@@@ -501,7 -516,7 +501,7 @@@ void board_init_r(gd_t *id, ulong dest_
        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
        bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
  
 -      monitor_flash_len = _end_ofs;
 +      monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start;
  
        /* Enable caches */
        enable_caches();
        debug("monitor flash len: %08lX\n", monitor_flash_len);
        board_init();   /* Setup chipselects */
        /*
-        * TODO: printing of the clock inforamtion of the board is now
+        * TODO: printing of the clock information of the board is now
         * implemented as part of bdinfo command. Currently only support for
         * davinci SOC's is added. Remove this check once all the board
         * implement this.
        mmc_initialize(gd->bd);
  #endif
  
 +#ifdef CONFIG_CMD_SCSI
 +      puts("SCSI:  ");
 +      scsi_init();
 +#endif
 +
  #ifdef CONFIG_HAS_DATAFLASH
        AT91F_DataflashInit();
        dataflash_print_info();
index 0291afa7bd531088f441808e9f9767cceb4d774b,f283248dfa750073a6fbd08329ea1ff7c2b66c90..751abe4e3c83f50f5fb5ad121c91f4603bd5051c
  
  DECLARE_GLOBAL_DATA_PTR;
  
 -void __arm_init_before_mmu(void)
 +__weak void arm_init_before_mmu(void)
  {
  }
 -void arm_init_before_mmu(void)
 -      __attribute__((weak, alias("__arm_init_before_mmu")));
  
  __weak void arm_init_domains(void)
  {
  }
  
- static void cp_delay (void)
- {
-       volatile int i;
-       /* copro seems to need some delay between reading and writing */
-       for (i = 0; i < 100; i++)
-               nop();
-       asm volatile("" : : : "memory");
- }
  void set_section_dcache(int section, enum dcache_option option)
  {
        u32 *page_table = (u32 *)gd->arch.tlb_addr;
        page_table[section] = value;
  }
  
 -void __mmu_page_table_flush(unsigned long start, unsigned long stop)
 +__weak void mmu_page_table_flush(unsigned long start, unsigned long stop)
  {
        debug("%s: Warning: not implemented\n", __func__);
  }
  
 -void mmu_page_table_flush(unsigned long start, unsigned long stop)
 -      __attribute__((weak, alias("__mmu_page_table_flush")));
 -
 -void mmu_set_region_dcache_behaviour(u32 start, int size,
 +void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
                                     enum dcache_option option)
  {
        u32 *page_table = (u32 *)gd->arch.tlb_addr;
 -      u32 upto, end;
 +      unsigned long upto, end;
  
        end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT;
        start = start >> MMU_SECTION_SHIFT;
 -      debug("%s: start=%x, size=%x, option=%d\n", __func__, start, size,
 +      debug("%s: start=%pa, size=%zu, option=%d\n", __func__, &start, size,
              option);
        for (upto = start; upto < end; upto++)
                set_section_dcache(upto, option);
@@@ -69,12 -64,10 +59,12 @@@ __weak void dram_bank_mmu_setup(int ban
  
        debug("%s: bank: %d\n", __func__, bank);
        for (i = bd->bi_dram[bank].start >> 20;
 -           i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
 +           i < (bd->bi_dram[bank].start >> 20) + (bd->bi_dram[bank].size >> 20);
             i++) {
  #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
                set_section_dcache(i, DCACHE_WRITETHROUGH);
 +#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
 +              set_section_dcache(i, DCACHE_WRITEALLOC);
  #else
                set_section_dcache(i, DCACHE_WRITEBACK);
  #endif
@@@ -96,18 -89,20 +86,20 @@@ static inline void mmu_setup(void
                dram_bank_mmu_setup(i);
        }
  
-       /* Copy the page table address to cp15 */
-       asm volatile("mcr p15, 0, %0, c2, c0, 0"
-                    : : "r" (gd->arch.tlb_addr) : "memory");
-       /* Set the access control to all-supervisor */
-       asm volatile("mcr p15, 0, %0, c3, c0, 0"
-                    : : "r" (~0));
+       asm volatile(
+               /* Copy the page table address to cp15 */
+               "mcr p15, 0, %0, c2, c0, 0\n"
+               /* Set the access control to all-supervisor */
+               "mcr p15, 0, %1, c3, c0, 0\n"
+               :
+               : "r"(gd->arch.tlb_addr), "r"(~0)
+               : "memory"
+               );
  
        arm_init_domains();
  
        /* and enable the mmu */
        reg = get_cr(); /* get control reg. */
-       cp_delay();
        set_cr(reg | CR_M);
  }
  
@@@ -125,7 -120,6 +117,6 @@@ static void cache_enable(uint32_t cache
        if ((cache_bit == CR_C) && !mmu_enabled())
                mmu_setup();
        reg = get_cr(); /* get control reg. */
-       cp_delay();
        set_cr(reg | cache_bit);
  }
  
@@@ -135,7 -129,6 +126,6 @@@ static void cache_disable(uint32_t cach
        uint32_t reg;
  
        reg = get_cr();
-       cp_delay();
  
        if (cache_bit == CR_C) {
                /* if cache isn;t enabled no need to disable */
                cache_bit |= CR_M;
        }
        reg = get_cr();
-       cp_delay();
        if (cache_bit == (CR_C | CR_M))
                flush_dcache_all();
        set_cr(reg & ~cache_bit);
diff --combined arch/arm/lib/cache.c
index 9cedeac6d641eb7b8548fb8571bcd6a261388fdb,8105e251104b0fff893a397e37009c2998331308..c89e0f40c3f1985d0a5df3948428b024f6ca0c75
@@@ -8,88 -8,46 +8,90 @@@
  /* for now: just dummy functions to satisfy the linker */
  
  #include <common.h>
 +#include <malloc.h>
  
 -void  __flush_cache(unsigned long start, unsigned long size)
 +__weak void flush_cache(unsigned long start, unsigned long size)
  {
 -#if defined(CONFIG_ARM1136)
 -      void arm1136_cache_flush(void);
 +#if defined(CONFIG_CPU_ARM1136)
  
 -      arm1136_cache_flush();
 +#if !defined(CONFIG_SYS_ICACHE_OFF)
 +      asm("mcr p15, 0, r1, c7, c5, 0"); /* invalidate I cache */
  #endif
- #ifdef CONFIG_CPU_ARM926EJS
-       /* test and clean, page 2-23 of arm926ejs manual */
-       asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory");
-       /* disable write buffer as well (page 2-22) */
-       asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
- #endif /* CONFIG_CPU_ARM926EJS */
 +
 +#if !defined(CONFIG_SYS_DCACHE_OFF)
 +      asm("mcr p15, 0, r1, c7, c14, 0"); /* Clean+invalidate D cache */
 +#endif
 +
 +#endif /* CONFIG_CPU_ARM1136 */
 +
+ #ifdef CONFIG_ARM926EJS
+       asm(
+               /* test and clean, page 2-23 of arm926ejs manual */
+               "0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n"
+               /* flush write buffer as well (page 2-22) */
+               "mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory"
+               );
+ #endif
        return;
  }
 -void  flush_cache(unsigned long start, unsigned long size)
 -      __attribute__((weak, alias("__flush_cache")));
  
  /*
   * Default implementation:
   * do a range flush for the entire range
   */
 -void  __flush_dcache_all(void)
 +__weak void flush_dcache_all(void)
  {
        flush_cache(0, ~0);
  }
 -void  flush_dcache_all(void)
 -      __attribute__((weak, alias("__flush_dcache_all")));
 -
  
  /*
   * Default implementation of enable_caches()
   * Real implementation should be in platform code
   */
 -void __enable_caches(void)
 +__weak void enable_caches(void)
  {
        puts("WARNING: Caches not enabled\n");
  }
 -void enable_caches(void)
 -      __attribute__((weak, alias("__enable_caches")));
 +
 +#ifdef CONFIG_SYS_NONCACHED_MEMORY
 +/*
 + * Reserve one MMU section worth of address space below the malloc() area that
 + * will be mapped uncached.
 + */
 +static unsigned long noncached_start;
 +static unsigned long noncached_end;
 +static unsigned long noncached_next;
 +
 +void noncached_init(void)
 +{
 +      phys_addr_t start, end;
 +      size_t size;
 +
 +      end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
 +      size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
 +      start = end - size;
 +
 +      debug("mapping memory %pa-%pa non-cached\n", &start, &end);
 +
 +      noncached_start = start;
 +      noncached_end = end;
 +      noncached_next = start;
 +
 +#ifndef CONFIG_SYS_DCACHE_OFF
 +      mmu_set_region_dcache_behaviour(noncached_start, size, DCACHE_OFF);
 +#endif
 +}
 +
 +phys_addr_t noncached_alloc(size_t size, size_t align)
 +{
 +      phys_addr_t next = ALIGN(noncached_next, align);
 +
 +      if (next >= noncached_end || (noncached_end - next) < size)
 +              return 0;
 +
 +      debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
 +      noncached_next = next + size;
 +
 +      return next;
 +}
 +#endif /* CONFIG_SYS_NONCACHED_MEMORY */
diff --combined arch/arm/lib/crt0.S
index 22df3e5b832c31a86cab5bbd2902b83c34a84033,7cfc52d6c2653f0a5d8699e3b4ddb2ce329f5142..8a774512b6d8a9429a8b60b53fd3911fc3811bb0
@@@ -62,27 -62,15 +62,27 @@@ ENTRY(_main
   */
  
  #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
-       ldr     sp, =(CONFIG_SPL_STACK)
+       ldr     sp, =CONFIG_SPL_STACK
  #else
-       ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
+       ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
  #endif
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
 -      sub     sp, #GD_SIZE    /* allocate one GD above SP */
 +      mov     r2, sp
 +      sub     sp, sp, #GD_SIZE        /* allocate one GD above SP */
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
 -      mov     r8, sp          /* GD is above SP */
 +      mov     r9, sp          /* GD is above SP */
 +      mov     r1, sp
        mov     r0, #0
 +clr_gd:
 +      cmp     r1, r2                  /* while not at end of GD */
 +      strlo   r0, [r1]                /* clear 32-bit GD word */
 +      addlo   r1, r1, #4              /* move to next */
 +      blo     clr_gd
 +#if defined(CONFIG_SYS_MALLOC_F_LEN)
 +      sub     sp, sp, #CONFIG_SYS_MALLOC_F_LEN
 +      str     sp, [r9, #GD_MALLOC_BASE]
 +#endif
 +      /* mov r0, #0 not needed due to above code */
        bl      board_init_f
  
  #if ! defined(CONFIG_SPL_BUILD)
   * 'here' but relocated.
   */
  
 -      ldr     sp, [r8, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
 +      ldr     sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
 -      ldr     r8, [r8, #GD_BD]                /* r8 = gd->bd */
 -      sub     r8, r8, #GD_SIZE                /* new GD is below bd */
 +      ldr     r9, [r9, #GD_BD]                /* r9 = gd->bd */
 +      sub     r9, r9, #GD_SIZE                /* new GD is below bd */
  
        adr     lr, here
 -      ldr     r0, [r8, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */
 +      ldr     r0, [r9, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */
        add     lr, lr, r0
 -      ldr     r0, [r8, #GD_RELOCADDR]         /* r0 = gd->relocaddr */
 +      ldr     r0, [r9, #GD_RELOCADDR]         /* r0 = gd->relocaddr */
        b       relocate_code
  here:
 +/*
 + * now relocate vectors
 + */
 +
 +      bl      relocate_vectors
  
  /* Set up final (full) environment */
  
@@@ -128,8 -111,8 +128,8 @@@ clbss_l:cmp        r0, r1                  /* while not at en
        bl red_led_on
  
        /* call board_init_r(gd_t *id, ulong dest_addr) */
 -      mov     r0, r8                  /* gd_t */
 -      ldr     r1, [r8, #GD_RELOCADDR] /* dest_addr */
 +      mov     r0, r9                  /* gd_t */
 +      ldr     r1, [r9, #GD_RELOCADDR] /* dest_addr */
        /* call board_init_r */
        ldr     pc, =board_init_r       /* this is auto-relocated! */
  
index 4dacfd941f6dd220cfa2f5d2a7ae006b10d628a2,e0aef1b48e89307c5ef0fee4c2618081fed9aa5b..3d6e5a3498cede8fd823fa340ea865668d4e53ff
   * (C) Copyright 2004
   * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #include <common.h>
 -#include <asm/ptrace.h>
 +#include <asm/proc-armv/ptrace.h>
 +#include <asm/u-boot-arm.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
  #ifdef CONFIG_USE_IRQ
  int interrupt_init (void)
  {
 +      unsigned long cpsr;
 +
        /*
         * setup up stacks if necessary
         */
        IRQ_STACK_START_IN = gd->irq_sp + 8;
        FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
  
 +
 +      __asm__ __volatile__("mrs %0, cpsr\n"
 +                           : "=r" (cpsr)
 +                           :
 +                           : "memory");
 +
 +      __asm__ __volatile__("msr cpsr_c, %0\n"
 +                           "mov sp, %1\n"
 +                           :
 +                           : "r" (IRQ_MODE | I_BIT | F_BIT | (cpsr & ~FIQ_MODE)),
 +                             "r" (IRQ_STACK_START)
 +                           : "memory");
 +
 +      __asm__ __volatile__("msr cpsr_c, %0\n"
 +                           "mov sp, %1\n"
 +                           :
 +                           : "r" (FIQ_MODE | I_BIT | F_BIT | (cpsr & ~IRQ_MODE)),
 +                             "r" (FIQ_STACK_START)
 +                           : "memory");
 +
 +      __asm__ __volatile__("msr cpsr_c, %0"
 +                           :
 +                           : "r" (cpsr)
 +                           : "memory");
 +
        return arch_interrupt_init();
  }
  
@@@ -131,16 -103,24 +131,24 @@@ void show_regs (struct pt_regs *regs
        "UK12_26",      "UK13_26",      "UK14_26",      "UK15_26",
        "USER_32",      "FIQ_32",       "IRQ_32",       "SVC_32",
        "UK4_32",       "UK5_32",       "UK6_32",       "ABT_32",
 -      "UK8_32",       "UK9_32",       "UK10_32",      "UND_32",
 +      "UK8_32",       "UK9_32",       "HYP_32",       "UND_32",
        "UK12_32",      "UK13_32",      "UK14_32",      "SYS_32",
        };
  
-       flags = condition_codes (regs);
-       printf ("pc : [<%08lx>]    lr : [<%08lx>]\n"
-               "sp : %08lx  ip : %08lx  fp : %08lx\n",
-               instruction_pointer (regs),
-               regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+       flags = condition_codes(regs);
+       if (gd->flags & GD_FLG_RELOC)
+               printf ("pc : [<%08lx>] (pre-reloc: [<%08lx>]) lr : [<%08lx>]\n"
+                       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+                       instruction_pointer(regs),
+                       instruction_pointer(regs) - gd->reloc_off,
+                       regs->ARM_lr, regs->ARM_sp,
+                       regs->ARM_ip, regs->ARM_fp);
+       else
+               printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+                       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+                       instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp,
+                       regs->ARM_ip, regs->ARM_fp);
        printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
                regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
        printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
                thumb_mode (regs) ? " (T)" : "");
  }
  
+ /* fixup PC to point to instruction leading to exception */
+ static inline void fixup_pc(struct pt_regs *regs, int offset)
+ {
+       uint32_t pc = instruction_pointer(regs) + offset;
+       regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
+ }
  void do_undefined_instruction (struct pt_regs *pt_regs)
  {
        printf ("undefined instruction\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
  }
  void do_software_interrupt (struct pt_regs *pt_regs)
  {
        printf ("software interrupt\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
  }
  void do_prefetch_abort (struct pt_regs *pt_regs)
  {
        printf ("prefetch abort\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
  }
  
  void do_data_abort (struct pt_regs *pt_regs)
  {
 -      unsigned long fsr;
 -
 -      /* Read Fault Status Register */
 -      asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r"(fsr));
 -
 -      printf ("data abort\n\n");
 -      if (fsr & 1)
 -              printf ("MAYBE you should read doc/README.arm-unaligned-accesses\n\n");
 +      printf ("data abort\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
  }
  void do_not_used (struct pt_regs *pt_regs)
  {
        printf ("not used\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
  }
  void do_fiq (struct pt_regs *pt_regs)
  {
        printf ("fast interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
  }
  void do_irq (struct pt_regs *pt_regs)
  {
        printf ("interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
  }
diff --combined arch/arm/lib/reset.c
index 9a95f085044ade0c8f62fe489263c455b08df221,3b057e3a3d8f9208a506799420d828453e4fa6f2..18d3e7eeffec16f71f0e5116d0bd66ee9e74eaea
  
  #include <common.h>
  
 +__weak void reset_misc(void)
 +{
 +}
 +
  int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
        puts ("resetting ...\n");
        udelay (50000);                         /* wait 50 ms */
  
        disable_interrupts();
 +
 +      reset_misc();
        reset_cpu(0);
-       /*NOTREACHED*/
-       return 0;
+       hang();
  }
diff --combined arch/arm/lib/vectors.S
index 49238ed21ed83766fe207c1060cef4e5b2d4257d,0000000000000000000000000000000000000000..1b51f003f35efb9bfb08c7cee1f895bfec0564fb
mode 100644,000000..100644
--- /dev/null
@@@ -1,291 -1,0 +1,295 @@@
 +/*
 + *  vectors - Generic ARM exception table code
 + *
 + *  Copyright (c) 1998        Dan Malek <dmalek@jlc.net>
 + *  Copyright (c) 1999        Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
 + *  Copyright (c) 2000        Wolfgang Denk <wd@denx.de>
 + *  Copyright (c) 2001        Alex Züpke <azu@sysgo.de>
 + *  Copyright (c) 2001        Marius Gröger <mag@sysgo.de>
 + *  Copyright (c) 2002        Alex Züpke <azu@sysgo.de>
 + *  Copyright (c) 2002        Gary Jennejohn <garyj@denx.de>
 + *  Copyright (c) 2002        Kyle Harris <kharris@nexus-tech.net>
 + *
 + * SPDX-License-Identifier:   GPL-2.0+
 + */
 +
 +#include <config.h>
 +
 +/*
 + *************************************************************************
 + *
 + * Symbol _start is referenced elsewhere, so make it global
 + *
 + *************************************************************************
 + */
 +
 +.globl _start
 +
 +/*
 + *************************************************************************
 + *
 + * Vectors have their own section so linker script can map them easily
 + *
 + *************************************************************************
 + */
 +
 +      .section ".vectors", "ax"
 +
 +/*
 + *************************************************************************
 + *
 + * Exception vectors as described in ARM reference manuals
 + *
 + * Uses indirect branch to allow reaching handlers anywhere in memory.
 + *
 + *************************************************************************
 + */
 +
 +_start:
 +
 +#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
 +      .word   CONFIG_SYS_DV_NOR_BOOT_CFG
 +#endif
 +
 +      b       reset
 +      ldr     pc, _undefined_instruction
 +      ldr     pc, _software_interrupt
 +      ldr     pc, _prefetch_abort
 +      ldr     pc, _data_abort
 +      ldr     pc, _not_used
 +      ldr     pc, _irq
 +      ldr     pc, _fiq
 +
 +/*
 + *************************************************************************
 + *
 + * Indirect vectors table
 + *
 + * Symbols referenced here must be defined somewhere else
 + *
 + *************************************************************************
 + */
 +
 +      .globl  _undefined_instruction
 +      .globl  _software_interrupt
 +      .globl  _prefetch_abort
 +      .globl  _data_abort
 +      .globl  _not_used
 +      .globl  _irq
 +      .globl  _fiq
 +
 +_undefined_instruction:       .word undefined_instruction
 +_software_interrupt:  .word software_interrupt
 +_prefetch_abort:      .word prefetch_abort
 +_data_abort:          .word data_abort
 +_not_used:            .word not_used
 +_irq:                 .word irq
 +_fiq:                 .word fiq
 +
 +      .balignl 16,0xdeadbeef
 +
 +/*
 + *************************************************************************
 + *
 + * Interrupt handling
 + *
 + *************************************************************************
 + */
 +
 +/* SPL interrupt handling: just hang */
 +
 +#ifdef CONFIG_SPL_BUILD
 +
 +      .align  5
 +undefined_instruction:
 +software_interrupt:
 +prefetch_abort:
 +data_abort:
 +not_used:
 +irq:
 +fiq:
 +
 +1:
 +      bl      1b                      /* hang and never return */
 +
 +#else /* !CONFIG_SPL_BUILD */
 +
 +/* IRQ stack memory (calculated at run-time) + 8 bytes */
 +.globl IRQ_STACK_START_IN
 +IRQ_STACK_START_IN:
++#ifndef IRAM_BASE_ADDR
 +      .word   0x0badc0de
++#else
++      .word   IRAM_BASE_ADDR + 0x20
++#endif
 +
 +#ifdef CONFIG_USE_IRQ
 +/* IRQ stack memory (calculated at run-time) */
 +.globl IRQ_STACK_START
 +IRQ_STACK_START:
 +      .word   0x0badc0de
 +
 +/* IRQ stack memory (calculated at run-time) */
 +.globl FIQ_STACK_START
 +FIQ_STACK_START:
 +      .word 0x0badc0de
 +
 +#endif /* CONFIG_USE_IRQ */
 +
 +@
 +@ IRQ stack frame.
 +@
 +#define S_FRAME_SIZE  72
 +
 +#define S_OLD_R0      68
 +#define S_PSR         64
 +#define S_PC          60
 +#define S_LR          56
 +#define S_SP          52
 +
 +#define S_IP          48
 +#define S_FP          44
 +#define S_R10         40
 +#define S_R9          36
 +#define S_R8          32
 +#define S_R7          28
 +#define S_R6          24
 +#define S_R5          20
 +#define S_R4          16
 +#define S_R3          12
 +#define S_R2          8
 +#define S_R1          4
 +#define S_R0          0
 +
 +#define MODE_SVC 0x13
 +#define I_BIT  0x80
 +
 +/*
 + * use bad_save_user_regs for abort/prefetch/undef/swi ...
 + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 + */
 +
 +      .macro  bad_save_user_regs
 +      @ carve out a frame on current user stack
 +      sub     sp, sp, #S_FRAME_SIZE
 +      stmia   sp, {r0 - r12}  @ Save user registers (now in svc mode) r0-r12
 +      ldr     r2, IRQ_STACK_START_IN
 +      @ get values for "aborted" pc and cpsr (into parm regs)
 +      ldmia   r2, {r2 - r3}
 +      add     r0, sp, #S_FRAME_SIZE           @ grab pointer to old stack
 +      add     r5, sp, #S_SP
 +      mov     r1, lr
 +      stmia   r5, {r0 - r3}   @ save sp_SVC, lr_SVC, pc, cpsr
 +      mov     r0, sp          @ save current stack into r0 (param register)
 +      .endm
 +
 +      .macro  irq_save_user_regs
 +      sub     sp, sp, #S_FRAME_SIZE
 +      stmia   sp, {r0 - r12}                  @ Calling r0-r12
 +      @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
 +      add     r8, sp, #S_PC
 +      stmdb   r8, {sp, lr}^           @ Calling SP, LR
 +      str     lr, [r8, #0]            @ Save calling PC
 +      mrs     r6, spsr
 +      str     r6, [r8, #4]            @ Save CPSR
 +      str     r0, [r8, #8]            @ Save OLD_R0
 +      mov     r0, sp
 +      .endm
 +
 +      .macro  irq_restore_user_regs
 +      ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
 +      mov     r0, r0
 +      ldr     lr, [sp, #S_PC]                 @ Get PC
 +      add     sp, sp, #S_FRAME_SIZE
 +      subs    pc, lr, #4              @ return & move spsr_svc into cpsr
 +      .endm
 +
 +      .macro get_bad_stack
 +      ldr     r13, IRQ_STACK_START_IN         @ setup our mode stack
 +
 +      str     lr, [r13]       @ save caller lr in position 0 of saved stack
 +      mrs     lr, spsr        @ get the spsr
 +      str     lr, [r13, #4]   @ save spsr in position 1 of saved stack
 +      mov     r13, #MODE_SVC  @ prepare SVC-Mode
 +      @ msr   spsr_c, r13
 +      msr     spsr, r13       @ switch modes, make sure moves will execute
 +      mov     lr, pc          @ capture return pc
 +      movs    pc, lr          @ jump to next instruction & switch modes.
 +      .endm
 +
 +      .macro get_irq_stack                    @ setup IRQ stack
 +      ldr     sp, IRQ_STACK_START
 +      .endm
 +
 +      .macro get_fiq_stack                    @ setup FIQ stack
 +      ldr     sp, FIQ_STACK_START
 +      .endm
 +
 +/*
 + * exception handlers
 + */
 +
 +      .align  5
 +undefined_instruction:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_undefined_instruction
 +
 +      .align  5
 +software_interrupt:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_software_interrupt
 +
 +      .align  5
 +prefetch_abort:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_prefetch_abort
 +
 +      .align  5
 +data_abort:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_data_abort
 +
 +      .align  5
 +not_used:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_not_used
 +
 +#ifdef CONFIG_USE_IRQ
 +
 +      .align  5
 +irq:
 +      get_irq_stack
 +      irq_save_user_regs
 +      bl      do_irq
 +      irq_restore_user_regs
 +
 +      .align  5
 +fiq:
 +      get_fiq_stack
 +      /* someone ought to write a more effiction fiq_save_user_regs */
 +      irq_save_user_regs
 +      bl      do_fiq
 +      irq_restore_user_regs
 +
 +#else
 +
 +      .align  5
 +irq:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_irq
 +
 +      .align  5
 +fiq:
 +      get_bad_stack
 +      bad_save_user_regs
 +      bl      do_fiq
 +
 +#endif /* CONFIG_USE_IRQ */
 +
 +#endif        /* CONFIG_SPL_BUILD */
index e8ea256be0c5c8d94198a15d4ed5e0da1cfead06,72745f63e3bf8304cf5bdc4ae0a7837a994134ba..c84c220047f3ab82cfcd3ac75cfff002f3e55ea7
@@@ -2,7 -2,7 +2,7 @@@
   * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
   * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #include <common.h>
  #include <asm/gpio.h>
  #include <asm/imx-common/iomux-v3.h>
  #include <asm/imx-common/mxc_i2c.h>
 +#include <asm/imx-common/sata.h>
 +#include <asm/imx-common/spi.h>
  #include <asm/imx-common/boot_mode.h>
 +#include <asm/imx-common/video.h>
  #include <mmc.h>
  #include <fsl_esdhc.h>
  #include <micrel.h>
  #include <miiphy.h>
  #include <netdev.h>
 -#include <linux/fb.h>
 -#include <ipu_pixfmt.h>
  #include <asm/arch/crm_regs.h>
  #include <asm/arch/mxc_hdmi.h>
  #include <i2c.h>
 +#include <input.h>
 +#include <netdev.h>
 +#include <usb/ehci-fsl.h>
  
  DECLARE_GLOBAL_DATA_PTR;
 +#define GP_USB_OTG_PWR        IMX_GPIO_NR(3, 22)
  
  #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                 \
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
@@@ -74,140 -69,123 +74,140 @@@ int dram_init(void
        return 0;
  }
  
 -iomux_v3_cfg_t const uart1_pads[] = {
 -      MX6_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +static iomux_v3_cfg_t const uart1_pads[] = {
 +      MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
 -iomux_v3_cfg_t const uart2_pads[] = {
 -      MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +static iomux_v3_cfg_t const uart2_pads[] = {
 +      MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
  #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  
  /* I2C1, SGTL5000 */
 -struct i2c_pads_info i2c_pad_info0 = {
 +static struct i2c_pads_info i2c_pad_info0 = {
        .scl = {
                .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
 -              .gpio_mode = MX6_PAD_EIM_D21__GPIO_3_21 | PC,
 +              .gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
                .gp = IMX_GPIO_NR(3, 21)
        },
        .sda = {
                .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
 -              .gpio_mode = MX6_PAD_EIM_D28__GPIO_3_28 | PC,
 +              .gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
                .gp = IMX_GPIO_NR(3, 28)
        }
  };
  
  /* I2C2 Camera, MIPI */
 -struct i2c_pads_info i2c_pad_info1 = {
 +static struct i2c_pads_info i2c_pad_info1 = {
        .scl = {
                .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
 -              .gpio_mode = MX6_PAD_KEY_COL3__GPIO_4_12 | PC,
 +              .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
                .gp = IMX_GPIO_NR(4, 12)
        },
        .sda = {
                .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
 -              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO_4_13 | PC,
 +              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
                .gp = IMX_GPIO_NR(4, 13)
        }
  };
  
  /* I2C3, J15 - RGB connector */
 -struct i2c_pads_info i2c_pad_info2 = {
 +static struct i2c_pads_info i2c_pad_info2 = {
        .scl = {
                .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
 -              .gpio_mode = MX6_PAD_GPIO_5__GPIO_1_5 | PC,
 +              .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | PC,
                .gp = IMX_GPIO_NR(1, 5)
        },
        .sda = {
                .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC,
 -              .gpio_mode = MX6_PAD_GPIO_16__GPIO_7_11 | PC,
 +              .gpio_mode = MX6_PAD_GPIO_16__GPIO7_IO11 | PC,
                .gp = IMX_GPIO_NR(7, 11)
        }
  };
  
 -iomux_v3_cfg_t const usdhc3_pads[] = {
 -      MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
 +static iomux_v3_cfg_t const usdhc2_pads[] = {
 +      MX6_PAD_SD2_CLK__SD2_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_CMD__SD2_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +};
 +
 +static iomux_v3_cfg_t const usdhc3_pads[] = {
 +      MX6_PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_SD3_DAT5__GPIO7_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_SD3_DAT5__GPIO7_IO00, /* CD */
  };
  
 -iomux_v3_cfg_t const usdhc4_pads[] = {
 -      MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
 +static iomux_v3_cfg_t const usdhc4_pads[] = {
 +      MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_NANDF_D6__GPIO2_IO06, /* CD */
  };
  
 -iomux_v3_cfg_t const enet_pads1[] = {
 +static iomux_v3_cfg_t const enet_pads1[] = {
        MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TXC__RGMII_TXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD0__RGMII_TD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD1__RGMII_TD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD2__RGMII_TD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD3__RGMII_TD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* pin 35 - 1 (PHY_AD2) on reset */
-       MX6_PAD_RGMII_RXC__GPIO6_IO30           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RXC__GPIO_6_30,
++      MX6_PAD_RGMII_RXC__GPIO6_IO30,
        /* pin 32 - 1 - (MODE0) all */
-       MX6_PAD_RGMII_RD0__GPIO6_IO25           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__GPIO_6_25,
++      MX6_PAD_RGMII_RD0__GPIO6_IO25,
        /* pin 31 - 1 - (MODE1) all */
-       MX6_PAD_RGMII_RD1__GPIO6_IO27           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__GPIO_6_27,
++      MX6_PAD_RGMII_RD1__GPIO6_IO27,
        /* pin 28 - 1 - (MODE2) all */
-       MX6_PAD_RGMII_RD2__GPIO6_IO28           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__GPIO_6_28,
++      MX6_PAD_RGMII_RD2__GPIO6_IO28,
        /* pin 27 - 1 - (MODE3) all */
-       MX6_PAD_RGMII_RD3__GPIO6_IO29           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__GPIO_6_29,
++      MX6_PAD_RGMII_RD3__GPIO6_IO29,
        /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-       MX6_PAD_RGMII_RX_CTL__GPIO6_IO24        | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
++      MX6_PAD_RGMII_RX_CTL__GPIO6_IO24,
        /* pin 42 PHY nRST */
-       MX6_PAD_EIM_D23__GPIO3_IO23             | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_ENET_RXD0__GPIO1_IO27           | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_EIM_D23__GPIO_3_23,
 -      MX6_PAD_ENET_RXD0__GPIO_1_27,
++      MX6_PAD_EIM_D23__GPIO3_IO23,
++      MX6_PAD_ENET_RXD0__GPIO1_IO27,
  };
  
 -iomux_v3_cfg_t const enet_pads2[] = {
 -      MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +static iomux_v3_cfg_t const enet_pads2[] = {
 +      MX6_PAD_RGMII_RXC__RGMII_RXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD0__RGMII_RD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD1__RGMII_RD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD2__RGMII_RD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
  };
  
 +static iomux_v3_cfg_t const misc_pads[] = {
 +      MX6_PAD_GPIO_1__USB_OTG_ID              | MUX_PAD_CTRL(WEAK_PULLUP),
 +      MX6_PAD_KEY_COL4__USB_OTG_OC            | MUX_PAD_CTRL(WEAK_PULLUP),
 +      MX6_PAD_EIM_D30__USB_H1_OC              | MUX_PAD_CTRL(WEAK_PULLUP),
 +      /* OTG Power enable */
 +      MX6_PAD_EIM_D22__GPIO3_IO22             | MUX_PAD_CTRL(OUTPUT_40OHM),
 +};
 +
  /* wl1271 pads on nitrogen6x */
 -iomux_v3_cfg_t const wl12xx_pads[] = {
 -      (MX6_PAD_NANDF_CS1__GPIO_6_14 & ~MUX_PAD_CTRL_MASK)
 +static iomux_v3_cfg_t const wl12xx_pads[] = {
 +      (MX6_PAD_NANDF_CS1__GPIO6_IO14 & ~MUX_PAD_CTRL_MASK)
                | MUX_PAD_CTRL(WEAK_PULLDOWN),
 -      (MX6_PAD_NANDF_CS2__GPIO_6_15 & ~MUX_PAD_CTRL_MASK)
 +      (MX6_PAD_NANDF_CS2__GPIO6_IO15 & ~MUX_PAD_CTRL_MASK)
                | MUX_PAD_CTRL(OUTPUT_40OHM),
 -      (MX6_PAD_NANDF_CS3__GPIO_6_16 & ~MUX_PAD_CTRL_MASK)
 +      (MX6_PAD_NANDF_CS3__GPIO6_IO16 & ~MUX_PAD_CTRL_MASK)
                | MUX_PAD_CTRL(OUTPUT_40OHM),
  };
  #define WL12XX_WL_IRQ_GP      IMX_GPIO_NR(6, 14)
  /* Button assignments for J14 */
  static iomux_v3_cfg_t const button_pads[] = {
        /* Menu */
 -      MX6_PAD_NANDF_D1__GPIO_2_1      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_NANDF_D1__GPIO2_IO01    | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
        /* Back */
 -      MX6_PAD_NANDF_D2__GPIO_2_2      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_NANDF_D2__GPIO2_IO02    | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
        /* Labelled Search (mapped to Power under Android) */
 -      MX6_PAD_NANDF_D3__GPIO_2_3      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_NANDF_D3__GPIO2_IO03    | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
        /* Home */
 -      MX6_PAD_NANDF_D4__GPIO_2_4      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_NANDF_D4__GPIO2_IO04    | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
        /* Volume Down */
 -      MX6_PAD_GPIO_19__GPIO_4_5       | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_GPIO_19__GPIO4_IO05     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
        /* Volume Up */
 -      MX6_PAD_GPIO_18__GPIO_7_13      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 +      MX6_PAD_GPIO_18__GPIO7_IO13     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
  };
  
  static void setup_iomux_enet(void)
        gpio_set_value(IMX_GPIO_NR(1, 27), 1); /* Nitrogen6X PHY reset */
  
        imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
 +      udelay(100);    /* Wait 100 us before using mii interface */
  }
  
 -iomux_v3_cfg_t const usb_pads[] = {
 -      MX6_PAD_GPIO_17__GPIO_7_12,
 +static iomux_v3_cfg_t const usb_pads[] = {
-       MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_GPIO_17__GPIO7_IO12,
  };
  
  static void setup_iomux_uart(void)
@@@ -273,19 -250,10 +273,19 @@@ int board_ehci_hcd_init(int port
  
        return 0;
  }
 +
 +int board_ehci_power(int port, int on)
 +{
 +      if (port)
 +              return 0;
 +      gpio_set_value(GP_USB_OTG_PWR, on);
 +      return 0;
 +}
 +
  #endif
  
  #ifdef CONFIG_FSL_ESDHC
 -struct fsl_esdhc_cfg usdhc_cfg[2] = {
 +static struct fsl_esdhc_cfg usdhc_cfg[2] = {
        {USDHC3_BASE_ADDR},
        {USDHC4_BASE_ADDR},
  };
  int board_mmc_getcd(struct mmc *mmc)
  {
        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 -      int ret;
 +      int gp_cd = (cfg->esdhc_base == USDHC3_BASE_ADDR) ? IMX_GPIO_NR(7, 0) :
 +                      IMX_GPIO_NR(2, 6);
  
 -      if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
 -              gpio_direction_input(IMX_GPIO_NR(7, 0));
 -              ret = !gpio_get_value(IMX_GPIO_NR(7, 0));
 -      } else {
 -              gpio_direction_input(IMX_GPIO_NR(2, 6));
 -              ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
 -      }
 -
 -      return ret;
 +      gpio_direction_input(gp_cd);
 +      return !gpio_get_value(gp_cd);
  }
  
  int board_mmc_init(bd_t *bis)
  {
 -      s32 status = 0;
 +      int ret;
        u32 index = 0;
  
        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
                       printf("Warning: you configured more USDHC controllers"
                               "(%d) then supported by the board (%d)\n",
                               index + 1, CONFIG_SYS_FSL_USDHC_NUM);
 -                     return status;
 +                     return -EINVAL;
                }
  
 -              status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              if (ret)
 +                      return ret;
        }
  
 -      return status;
 +      return 0;
  }
  #endif
  
  #ifdef CONFIG_MXC_SPI
 -iomux_v3_cfg_t const ecspi1_pads[] = {
 +int board_spi_cs_gpio(unsigned bus, unsigned cs)
 +{
 +      return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
 +}
 +
 +static iomux_v3_cfg_t const ecspi1_pads[] = {
        /* SS1 */
-       MX6_PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_EIM_D19__GPIO_3_19   | MUX_PAD_CTRL(SPI_PAD_CTRL),
++      MX6_PAD_EIM_D19__GPIO3_IO19,
        MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
  };
  
 -void setup_spi(void)
 +static void setup_spi(void)
  {
        imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
                                         ARRAY_SIZE(ecspi1_pads));
@@@ -402,11 -369,6 +402,11 @@@ int board_eth_init(bd_t *bis
                free(bus);
        }
  #endif
 +
 +#ifdef CONFIG_CI_UDC
 +      /* For otg ethernet*/
 +      usb_eth_initialize(bis);
 +#endif
        return 0;
  }
  
@@@ -416,53 -378,108 +416,53 @@@ static void setup_buttons(void
                                         ARRAY_SIZE(button_pads));
  }
  
 -#ifdef CONFIG_CMD_SATA
 -
 -int setup_sata(void)
 -{
 -      struct iomuxc_base_regs *const iomuxc_regs
 -              = (struct iomuxc_base_regs *) IOMUXC_BASE_ADDR;
 -      int ret = enable_sata_clock();
 -      if (ret)
 -              return ret;
 -
 -      clrsetbits_le32(&iomuxc_regs->gpr[13],
 -                      IOMUXC_GPR13_SATA_MASK,
 -                      IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB
 -                      |IOMUXC_GPR13_SATA_PHY_7_SATA2M
 -                      |IOMUXC_GPR13_SATA_SPEED_3G
 -                      |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT)
 -                      |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED
 -                      |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16
 -                      |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB
 -                      |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V
 -                      |IOMUXC_GPR13_SATA_PHY_1_SLOW);
 -
 -      return 0;
 -}
 -#endif
 -
  #if defined(CONFIG_VIDEO_IPUV3)
  
  static iomux_v3_cfg_t const backlight_pads[] = {
        /* Backlight on RGB connector: J15 */
-       MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_SD1_DAT3__GPIO_1_21,
++      MX6_PAD_SD1_DAT3__GPIO1_IO21,
  #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
  
        /* Backlight on LVDS connector: J6 */
-       MX6_PAD_SD1_CMD__GPIO1_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_SD1_CMD__GPIO_1_18,
++      MX6_PAD_SD1_CMD__GPIO1_IO18,
  #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
  };
  
  static iomux_v3_cfg_t const rgb_pads[] = {
        MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
        MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
 -      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2,
 -      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3,
 -      MX6_PAD_DI0_PIN4__GPIO_4_20,
 -      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
 -      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
 -      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
 -      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
 -      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
 -      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
 -      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
 -      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
 -      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
 -      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
 -      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
 -      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
 -      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
 -      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
 -      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
 -      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
 -      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
 -      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
 -      MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
 -      MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
 -      MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
 -      MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
 -      MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
 -      MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
 +      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
 +      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
 +      MX6_PAD_DI0_PIN4__GPIO4_IO20,
 +      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
 +      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
 +      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
 +      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
 +      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
 +      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
 +      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
 +      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
 +      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
 +      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
 +      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
 +      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
 +      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
 +      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
 +      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
 +      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
 +      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
 +      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
 +      MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
 +      MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
 +      MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
 +      MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
 +      MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
 +      MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
  };
  
 -struct display_info_t {
 -      int     bus;
 -      int     addr;
 -      int     pixfmt;
 -      int     (*detect)(struct display_info_t const *dev);
 -      void    (*enable)(struct display_info_t const *dev);
 -      struct  fb_videomode mode;
 -};
 -
 -
 -static int detect_hdmi(struct display_info_t const *dev)
 -{
 -      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 -      return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
 -}
 -
 -static void enable_hdmi(struct display_info_t const *dev)
 +static void do_enable_hdmi(struct display_info_t const *dev)
  {
 -      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 -      u8 reg;
 -      printf("%s: setup HDMI monitor\n", __func__);
 -      reg = readb(&hdmi->phy_conf0);
 -      reg |= HDMI_PHY_CONF0_PDZ_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -
 -      udelay(3000);
 -      reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -      udelay(3000);
 -      reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -      writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
 +      imx_enable_hdmi_phy();
  }
  
  static int detect_i2c(struct display_info_t const *dev)
@@@ -482,17 -499,6 +482,17 @@@ static void enable_lvds(struct display_
        gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
  }
  
 +static void enable_lvds_jeida(struct display_info_t const *dev)
 +{
 +      struct iomuxc *iomux = (struct iomuxc *)
 +                              IOMUXC_BASE_ADDR;
 +      u32 reg = readl(&iomux->gpr[2]);
 +      reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
 +           |IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA;
 +      writel(reg, &iomux->gpr[2]);
 +      gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
 +}
 +
  static void enable_rgb(struct display_info_t const *dev)
  {
        imx_iomux_v3_setup_multiple_pads(
        gpio_direction_output(RGB_BACKLIGHT_GP, 1);
  }
  
 -static struct display_info_t const displays[] = {{
 -      .bus    = -1,
 -      .addr   = 0,
 +struct display_info_t const displays[] = {{
 +      .bus    = 1,
 +      .addr   = 0x50,
        .pixfmt = IPU_PIX_FMT_RGB24,
 -      .detect = detect_hdmi,
 -      .enable = enable_hdmi,
 +      .detect = detect_i2c,
 +      .enable = do_enable_hdmi,
        .mode   = {
                .name           = "HDMI",
                .refresh        = 60,
                .vsync_len      = 10,
                .sync           = FB_SYNC_EXT,
                .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = NULL,
 +      .enable = enable_lvds_jeida,
 +      .mode   = {
 +              .name           = "LDB-WXGA",
 +              .refresh        = 60,
 +              .xres           = 1280,
 +              .yres           = 800,
 +              .pixclock       = 14065,
 +              .left_margin    = 40,
 +              .right_margin   = 40,
 +              .upper_margin   = 3,
 +              .lower_margin   = 80,
 +              .hsync_len      = 10,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = NULL,
 +      .enable = enable_lvds,
 +      .mode   = {
 +              .name           = "LDB-WXGA-S",
 +              .refresh        = 60,
 +              .xres           = 1280,
 +              .yres           = 800,
 +              .pixclock       = 14065,
 +              .left_margin    = 40,
 +              .right_margin   = 40,
 +              .upper_margin   = 3,
 +              .lower_margin   = 80,
 +              .hsync_len      = 10,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
  } }, {
        .bus    = 2,
        .addr   = 0x4,
                .vsync_len      = 10,
                .sync           = FB_SYNC_EXT,
                .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_LVDS666,
 +      .detect = NULL,
 +      .enable = enable_lvds,
 +      .mode   = {
 +              .name           = "LG-9.7",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 768,
 +              .pixclock       = 15385, /* ~65MHz */
 +              .left_margin    = 480,
 +              .right_margin   = 260,
 +              .upper_margin   = 16,
 +              .lower_margin   = 6,
 +              .hsync_len      = 250,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
  } }, {
        .bus    = 2,
        .addr   = 0x38,
                .vsync_len      = 10,
                .sync           = FB_SYNC_EXT,
                .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 2,
 +      .addr   = 0x10,
 +      .pixfmt = IPU_PIX_FMT_RGB666,
 +      .detect = detect_i2c,
 +      .enable = enable_rgb,
 +      .mode   = {
 +              .name           = "fusion7",
 +              .refresh        = 60,
 +              .xres           = 800,
 +              .yres           = 480,
 +              .pixclock       = 33898,
 +              .left_margin    = 96,
 +              .right_margin   = 24,
 +              .upper_margin   = 3,
 +              .lower_margin   = 10,
 +              .hsync_len      = 72,
 +              .vsync_len      = 7,
 +              .sync           = 0x40000002,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB666,
 +      .detect = NULL,
 +      .enable = enable_rgb,
 +      .mode   = {
 +              .name           = "svga",
 +              .refresh        = 60,
 +              .xres           = 800,
 +              .yres           = 600,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = 0,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 2,
 +      .addr   = 0x41,
 +      .pixfmt = IPU_PIX_FMT_LVDS666,
 +      .detect = detect_i2c,
 +      .enable = enable_lvds,
 +      .mode   = {
 +              .name           = "amp1024x600",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 600,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_LVDS666,
 +      .detect = 0,
 +      .enable = enable_lvds,
 +      .mode   = {
 +              .name           = "wvga-lvds",
 +              .refresh        = 57,
 +              .xres           = 800,
 +              .yres           = 480,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
  } }, {
        .bus    = 2,
        .addr   = 0x48,
                .vsync_len      = 10,
                .sync           = 0,
                .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = NULL,
 +      .enable = enable_rgb,
 +      .mode   = {
 +              .name           = "qvga",
 +              .refresh        = 60,
 +              .xres           = 320,
 +              .yres           = 240,
 +              .pixclock       = 37037,
 +              .left_margin    = 38,
 +              .right_margin   = 37,
 +              .upper_margin   = 16,
 +              .lower_margin   = 15,
 +              .hsync_len      = 30,
 +              .vsync_len      = 3,
 +              .sync           = 0,
 +              .vmode          = FB_VMODE_NONINTERLACED
  } } };
 +size_t display_count = ARRAY_SIZE(displays);
  
 -int board_video_skip(void)
 +int board_cfb_skip(void)
  {
 -      int i;
 -      int ret;
 -      char const *panel = getenv("panel");
 -      if (!panel) {
 -              for (i = 0; i < ARRAY_SIZE(displays); i++) {
 -                      struct display_info_t const *dev = displays+i;
 -                      if (dev->detect(dev)) {
 -                              panel = dev->mode.name;
 -                              printf("auto-detected panel %s\n", panel);
 -                              break;
 -                      }
 -              }
 -              if (!panel) {
 -                      panel = displays[0].mode.name;
 -                      printf("No panel detected: default to %s\n", panel);
 -              }
 -      } else {
 -              for (i = 0; i < ARRAY_SIZE(displays); i++) {
 -                      if (!strcmp(panel, displays[i].mode.name))
 -                              break;
 -              }
 -      }
 -      if (i < ARRAY_SIZE(displays)) {
 -              ret = ipuv3_fb_init(&displays[i].mode, 0,
 -                                  displays[i].pixfmt);
 -              if (!ret) {
 -                      displays[i].enable(displays+i);
 -                      printf("Display: %s (%ux%u)\n",
 -                             displays[i].mode.name,
 -                             displays[i].mode.xres,
 -                             displays[i].mode.yres);
 -              } else
 -                      printf("LCD %s cannot be configured: %d\n",
 -                             displays[i].mode.name, ret);
 -      } else {
 -              printf("unsupported panel %s\n", panel);
 -              ret = -EINVAL;
 -      }
 -      return (0 != ret);
 +      return NULL != getenv("novideo");
  }
  
  static void setup_display(void)
  {
        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 -      struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 -      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 -
        int reg;
  
 +      enable_ipu_clock();
 +      imx_setup_hdmi();
        /* Turn on LDB0,IPU,IPU DI0 clocks */
        reg = __raw_readl(&mxc_ccm->CCGR3);
 -      reg |=   MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
 -              |MXC_CCM_CCGR3_LDB_DI0_MASK;
 +      reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
        writel(reg, &mxc_ccm->CCGR3);
  
 -      /* Turn on HDMI PHY clock */
 -      reg = __raw_readl(&mxc_ccm->CCGR2);
 -      reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
 -             |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
 -      writel(reg, &mxc_ccm->CCGR2);
 -
 -      /* clear HDMI PHY reset */
 -      writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
 -
 -      /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
 -      writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
 -      writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
 -
        /* set LDB0, LDB1 clk select to 011/011 */
        reg = readl(&mxc_ccm->cs2cdr);
        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
        writel(reg, &mxc_ccm->cscmr2);
  
        reg = readl(&mxc_ccm->chsccdr);
 -      reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
 -              |MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
 -              |MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 -              <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
 -            |(CHSCCDR_PODF_DIVIDE_BY_3
 -              <<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 -            |(CHSCCDR_IPU_PRE_CLK_540M_PFD
 -              <<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 +              <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
        writel(reg, &mxc_ccm->chsccdr);
  
        reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
        writel(reg, &iomux->gpr[2]);
  
        reg = readl(&iomux->gpr[3]);
 -      reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
 +      reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
 +                      |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
            | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
               <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
        writel(reg, &iomux->gpr[3]);
  }
  #endif
  
 +static iomux_v3_cfg_t const init_pads[] = {
 +      /* SGTL5000 sys_mclk */
 +      NEW_PAD_CTRL(MX6_PAD_GPIO_0__CCM_CLKO1, OUTPUT_40OHM),
 +
 +      /* J5 - Camera MCLK */
 +      NEW_PAD_CTRL(MX6_PAD_GPIO_3__CCM_CLKO2, OUTPUT_40OHM),
 +
 +      /* wl1271 pads on nitrogen6x */
 +      /* WL12XX_WL_IRQ_GP */
 +      NEW_PAD_CTRL(MX6_PAD_NANDF_CS1__GPIO6_IO14, WEAK_PULLDOWN),
 +      /* WL12XX_WL_ENABLE_GP */
 +      NEW_PAD_CTRL(MX6_PAD_NANDF_CS2__GPIO6_IO15, OUTPUT_40OHM),
 +      /* WL12XX_BT_ENABLE_GP */
 +      NEW_PAD_CTRL(MX6_PAD_NANDF_CS3__GPIO6_IO16, OUTPUT_40OHM),
 +      /* USB otg power */
 +      NEW_PAD_CTRL(MX6_PAD_EIM_D22__GPIO3_IO22, OUTPUT_40OHM),
 +      NEW_PAD_CTRL(MX6_PAD_NANDF_D5__GPIO2_IO05, OUTPUT_40OHM),
 +      NEW_PAD_CTRL(MX6_PAD_NANDF_WP_B__GPIO6_IO09, OUTPUT_40OHM),
 +      NEW_PAD_CTRL(MX6_PAD_GPIO_8__GPIO1_IO08, OUTPUT_40OHM),
 +      NEW_PAD_CTRL(MX6_PAD_GPIO_6__GPIO1_IO06, OUTPUT_40OHM),
 +};
 +
 +#define WL12XX_WL_IRQ_GP      IMX_GPIO_NR(6, 14)
 +
 +static unsigned gpios_out_low[] = {
 +      /* Disable wl1271 */
 +      IMX_GPIO_NR(6, 15),     /* disable wireless */
 +      IMX_GPIO_NR(6, 16),     /* disable bluetooth */
 +      IMX_GPIO_NR(3, 22),     /* disable USB otg power */
 +      IMX_GPIO_NR(2, 5),      /* ov5640 mipi camera reset */
 +      IMX_GPIO_NR(1, 8),      /* ov5642 reset */
 +};
 +
 +static unsigned gpios_out_high[] = {
 +      IMX_GPIO_NR(1, 6),      /* ov5642 powerdown */
 +      IMX_GPIO_NR(6, 9),      /* ov5640 mipi camera power down */
 +};
 +
 +static void set_gpios(unsigned *p, int cnt, int val)
 +{
 +      int i;
 +
 +      for (i = 0; i < cnt; i++)
 +              gpio_direction_output(*p++, val);
 +}
 +
  int board_early_init_f(void)
  {
        setup_iomux_uart();
  
 -      /* Disable wl1271 For Nitrogen6w */
 +      set_gpios(gpios_out_high, ARRAY_SIZE(gpios_out_high), 1);
 +      set_gpios(gpios_out_low, ARRAY_SIZE(gpios_out_low), 0);
        gpio_direction_input(WL12XX_WL_IRQ_GP);
 -      gpio_direction_output(WL12XX_WL_ENABLE_GP, 0);
 -      gpio_direction_output(WL12XX_BT_ENABLE_GP, 0);
  
        imx_iomux_v3_setup_multiple_pads(wl12xx_pads, ARRAY_SIZE(wl12xx_pads));
 +      imx_iomux_v3_setup_multiple_pads(init_pads, ARRAY_SIZE(init_pads));
        setup_buttons();
  
  #if defined(CONFIG_VIDEO_IPUV3)
@@@ -880,22 -738,12 +880,22 @@@ int overwrite_console(void
  
  int board_init(void)
  {
 +      struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
 +
 +      clrsetbits_le32(&iomuxc_regs->gpr[1],
 +                      IOMUXC_GPR1_OTG_ID_MASK,
 +                      IOMUXC_GPR1_OTG_ID_GPIO1);
 +
 +      imx_iomux_v3_setup_multiple_pads(misc_pads, ARRAY_SIZE(misc_pads));
 +
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  
  #ifdef CONFIG_MXC_SPI
        setup_spi();
  #endif
 +      imx_iomux_v3_setup_multiple_pads(
 +              usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
        setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
        setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
        setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
index 749253429b15949de3b02e7330fcc3553c9c6b05,0d07f1b8a349610e32c4a035522534e0e6d2b80d..ac64bcc9118a5bdd11977eb71420651548ed060b
@@@ -4,7 -4,7 +4,7 @@@
   * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
   * Leo Sartre, <lsartre@adeneo-embedded.com>
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #include <common.h>
@@@ -35,32 -35,32 +35,32 @@@ int dram_init(void
  }
  
  iomux_v3_cfg_t const uart2_pads[] = {
 -      MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
  iomux_v3_cfg_t const usdhc2_pads[] = {
 -      MX6_PAD_SD2_CLK__USDHC2_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_CMD__USDHC2_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT0__USDHC2_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT1__USDHC2_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT2__USDHC2_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT3__USDHC2_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_GPIO_4__GPIO_1_4      | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_CLK__SD2_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_CMD__SD2_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_GPIO_4__GPIO1_IO04      | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  };
  
  iomux_v3_cfg_t const usdhc4_pads[] = {
 -      MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
 +      MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_NANDF_D6__GPIO2_IO06, /* CD */
  };
  
  static void setup_iomux_uart(void)
index 5a1010e59550a4c65d9e2fc2ad3922ae0e5f9660,b7c09347bdd8a7529a4d1137519982df66ea43c6..8044a717d66ec16d03b542b6e79d0b932b24daac
@@@ -200,7 -200,57 +200,57 @@@ const iomux_cfg_t iomux_setup[] = 
                (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP),
  };
  
 -void board_init_ll(void)
 +void board_init_ll(const uint32_t arg, const uint32_t *resptr)
  {
 -      mxs_common_spl_init(iomux_setup, ARRAY_SIZE(iomux_setup));
 +      mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup));
  }
+ static uint32_t dram_vals[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00010101, 0x01010101, 0x000f0f01, 0x0f02020a,
+       0x00000000, 0x00010101, 0x00000100, 0x00000100, 0x00000000,
+       0x00000002, 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
+       0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612, 0x02030202,
+       0x00c8001c, 0x00000000, 0x00000000, 0x00012100, 0xffff0303,
+       0x00012100, 0xffff0303, 0x00012100, 0xffff0303, 0x00012100,
+       0xffff0303, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000612, 0x01000F02, 0x06120612, 0x00000200,
+       0x00020007, 0xf5014b27, 0xf5014b27, 0xf5014b27, 0xf5014b27,
+       0x07000300, 0x07000300, 0x07000300, 0x07000300, 0x00000006,
+       0x00000000, 0x00000000, 0x01000000, 0x01020408, 0x08040201,
+       0x000f1133, 0x00000000, 0x00001f04, 0x00001f04, 0x00001f04,
+       0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00010000, 0x00020304, 0x00000004,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x01010000, 0x01000000, 0x03030000, 0x00010303,
+       0x01020202, 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       0x06120612, 0x04320432, 0x04320432, 0x00040004, 0x00040004,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001
+ };
+ void mx28_ddr2_setup(void)
+ {
+       int i;
+       serial_puts("\n");
+       for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
+               writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+ }
index 98ccdb785b3498fa15406f628e84cbbd1da859aa,4dae0231dc4a93a004ea0556de3e731c59f48f4b..abe56c9e31da2b08cf34cb043af04e9ca7030500
@@@ -7,7 -7,7 +7,7 @@@
  #include <common.h>
  #include <asm/io.h>
  #include <asm/arch/imx-regs.h>
 -#include <asm/arch/mx6q_pins.h>
 +#include <asm/arch/mx6-pins.h>
  #include <asm/arch/clock.h>
  #include <asm/errno.h>
  #include <asm/gpio.h>
@@@ -16,7 -16,6 +16,7 @@@
  #include <fsl_esdhc.h>
  #include <miiphy.h>
  #include <netdev.h>
 +#include <usb.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
  
  int dram_init(void)
  {
 -      gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
 +#if defined(CONFIG_MX6DL) && !defined(CONFIG_MX6DL_LPDDR2) && \
 +      defined(CONFIG_DDR_32BIT)
 +      gd->ram_size = ((phys_size_t)CONFIG_DDR_MB * 1024 * 1024) / 2;
 +#else
 +      gd->ram_size = (phys_size_t)CONFIG_DDR_MB * 1024 * 1024;
 +#endif
  
        return 0;
  }
  
  iomux_v3_cfg_t const uart4_pads[] = {
 -      MX6_PAD_KEY_COL0__UART4_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_KEY_ROW0__UART4_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
  iomux_v3_cfg_t const usdhc3_pads[] = {
 -      MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_CS0__GPIO_6_11, /* CD */
 +      MX6_PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_CS0__GPIO6_IO11  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_NANDF_CS0__GPIO6_IO11, /* CD */
  };
  
  iomux_v3_cfg_t const usdhc4_pads[] = {
 -      MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  };
  
  iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_KEY_COL1__ENET_MDIO        | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_KEY_COL2__ENET_MDC         | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TXC__ENET_RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD0__ENET_RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD1__ENET_RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD2__ENET_RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD3__ENET_RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TXC__RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD0__RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD1__RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD2__RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD3__RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RXC__ENET_RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__ENET_RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__ENET_RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__ENET_RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__ENET_RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RXC__RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD0__RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD1__RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD2__RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD3__RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  };
  
@@@ -126,7 -120,7 +126,7 @@@ int board_mmc_getcd(struct mmc *mmc
  
  int board_mmc_init(bd_t *bis)
  {
 -      s32 status = 0;
 +      int ret;
        u32 index = 0;
  
        usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
                        printf("Warning: you configured more USDHC controllers"
                                "(%d) then supported by the board (%d)\n",
                                index + 1, CONFIG_SYS_FSL_USDHC_NUM);
 -                      return status;
 +                      return -EINVAL;
                }
  
 -              status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              if (ret)
 +                      return ret;
        }
  
 -      return status;
 +      return 0;
  }
  #endif
  
@@@ -194,10 -186,13 +194,10 @@@ int fecmxc_mii_postcall(int phy
  int board_eth_init(bd_t *bis)
  {
        struct eth_device *dev;
 -      int ret;
 +      int ret = cpu_eth_init(bis);
  
 -      ret = cpu_eth_init(bis);
 -      if (ret) {
 -              printf("FEC MXC: %s:failed\n", __func__);
 +      if (ret)
                return ret;
 -      }
  
        dev = eth_get_dev_by_name("FEC");
        if (!dev) {
        return 0;
  }
  
-       MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
 +#ifdef CONFIG_USB_EHCI_MX6
 +#define USB_OTHERREGS_OFFSET  0x800
 +#define UCTRL_PWR_POL         (1 << 9)
 +
 +static iomux_v3_cfg_t const usb_otg_pads[] = {
++      MX6_PAD_EIM_D22__USB_OTG_PWR,
++      MX6_PAD_GPIO_1__USB_OTG_ID,
 +};
 +
 +static void setup_usb(void)
 +{
 +      imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 +                                       ARRAY_SIZE(usb_otg_pads));
 +
 +      /*
 +       * set daisy chain for otg_pin_id on 6q.
 +       * for 6dl, this bit is reserved
 +       */
 +      imx_iomux_set_gpr_register(1, 13, 1, 1);
 +}
 +
 +int board_ehci_hcd_init(int port)
 +{
 +      u32 *usbnc_usb_ctrl;
 +
 +      if (port > 0)
 +              return -EINVAL;
 +
 +      usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
 +                               port * 4);
 +
 +      setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
 +
 +      return 0;
 +}
 +#endif
 +
  int board_early_init_f(void)
  {
        setup_iomux_uart();
@@@ -264,20 -222,12 +264,20 @@@ int board_init(void
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  
 +#ifdef CONFIG_USB_EHCI_MX6
 +      setup_usb();
 +#endif
 +
        return 0;
  }
  
  int checkboard(void)
  {
 +#ifdef CONFIG_MX6DL
 +      puts("Board: MX6DL-Armadillo2\n");
 +#else
        puts("Board: MX6Q-Armadillo2\n");
 +#endif
  
        return 0;
  }
index 59387ffaaa7e7960e625f3b8e0833f7f297dee23,d454d64dec858fc5d284bf73b5739301be2e0eb9..c7a790f527fd7465c9476e0dfb373898daf5a939
  #include <asm/arch/clock.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/iomux.h>
 -#include <asm/arch/mx6q_pins.h>
 +#include <asm/arch/mx6-pins.h>
  #include <asm/errno.h>
  #include <asm/gpio.h>
  #include <asm/imx-common/iomux-v3.h>
  #include <asm/imx-common/mxc_i2c.h>
  #include <asm/imx-common/boot_mode.h>
 +#include <asm/imx-common/spi.h>
  #include <mmc.h>
  #include <fsl_esdhc.h>
  #include <miiphy.h>
  #include <netdev.h>
  #include <asm/arch/sys_proto.h>
  #include <i2c.h>
 +#include <asm/arch/mxc_hdmi.h>
 +#include <asm/imx-common/video.h>
 +#include <asm/arch/crm_regs.h>
 +#include <pca953x.h>
 +#include <power/pmic.h>
 +#include "../common/pfuze.h"
  
  DECLARE_GLOBAL_DATA_PTR;
  
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
        PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  
 +#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
 +#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
 +                      PAD_CTL_SRE_FAST)
 +#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
 +
  #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  
 +#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |          \
 +      PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
 +      PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
 +
 +#define I2C_PMIC      1
 +
  int dram_init(void)
  {
        gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
        return 0;
  }
  
 -iomux_v3_cfg_t const uart4_pads[] = {
 -      MX6_PAD_KEY_COL0__UART4_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_KEY_ROW0__UART4_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +static iomux_v3_cfg_t const uart4_pads[] = {
 +      MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
 -iomux_v3_cfg_t const enet_pads[] = {
 +static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_KEY_COL1__ENET_MDIO             | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_KEY_COL2__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TXC__RGMII_TXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD0__RGMII_TD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD1__RGMII_TD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD2__RGMII_TD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD3__RGMII_TD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RXC__RGMII_RXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD0__RGMII_RD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD1__RGMII_RD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD2__RGMII_RD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
  };
  
  /* I2C2 PMIC, iPod, Tuner, Codec, Touch, HDMI EDID, MIPI CSI2 card */
 -struct i2c_pads_info i2c_pad_info1 = {
 +static struct i2c_pads_info i2c_pad_info1 = {
        .scl = {
                .i2c_mode = MX6_PAD_EIM_EB2__I2C2_SCL | PC,
 -              .gpio_mode = MX6_PAD_EIM_EB2__GPIO_2_30 | PC,
 +              .gpio_mode = MX6_PAD_EIM_EB2__GPIO2_IO30 | PC,
                .gp = IMX_GPIO_NR(2, 30)
        },
        .sda = {
                .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
 -              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO_4_13 | PC,
 +              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
                .gp = IMX_GPIO_NR(4, 13)
        }
  };
  
 +#ifndef CONFIG_SYS_FLASH_CFI
  /*
   * I2C3 MLB, Port Expanders (A, B, C), Video ADC, Light Sensor,
   * Compass Sensor, Accelerometer, Res Touch
   */
 -struct i2c_pads_info i2c_pad_info2 = {
 +static struct i2c_pads_info i2c_pad_info2 = {
        .scl = {
                .i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
 -              .gpio_mode = MX6_PAD_GPIO_3__GPIO_1_3 | PC,
 +              .gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
                .gp = IMX_GPIO_NR(1, 3)
        },
        .sda = {
                .i2c_mode = MX6_PAD_EIM_D18__I2C3_SDA | PC,
 -              .gpio_mode = MX6_PAD_EIM_D18__GPIO_3_18 | PC,
 +              .gpio_mode = MX6_PAD_EIM_D18__GPIO3_IO18 | PC,
                .gp = IMX_GPIO_NR(3, 18)
        }
  };
-       MX6_PAD_EIM_A24__GPIO5_IO04             | MUX_PAD_CTRL(NO_PAD_CTRL),
 +#endif
 +
 +static iomux_v3_cfg_t const i2c3_pads[] = {
++      MX6_PAD_EIM_A24__GPIO5_IO04,
 +};
  
 -iomux_v3_cfg_t const i2c3_pads[] = {
 -      MX6_PAD_EIM_A24__GPIO_5_4,
 +static iomux_v3_cfg_t const port_exp[] = {
-       MX6_PAD_SD2_DAT0__GPIO1_IO15            | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_SD2_DAT0__GPIO1_IO15,
  };
  
 -iomux_v3_cfg_t const port_exp[] = {
 -      MX6_PAD_SD2_DAT0__GPIO_1_15,
 +/*Define for building port exp gpio, pin starts from 0*/
 +#define PORTEXP_IO_NR(chip, pin) \
 +      ((chip << 5) + pin)
 +
 +/*Get the chip addr from a ioexp gpio*/
 +#define PORTEXP_IO_TO_CHIP(gpio_nr) \
 +      (gpio_nr >> 5)
 +
 +/*Get the pin number from a ioexp gpio*/
 +#define PORTEXP_IO_TO_PIN(gpio_nr) \
 +      (gpio_nr & 0x1f)
 +
 +static int port_exp_direction_output(unsigned gpio, int value)
 +{
 +      int ret;
 +
 +      i2c_set_bus_num(2);
 +      ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
 +      if (ret)
 +              return ret;
 +
 +      ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
 +              (1 << PORTEXP_IO_TO_PIN(gpio)),
 +              (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
 +
 +      if (ret)
 +              return ret;
 +
 +      ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
 +              (1 << PORTEXP_IO_TO_PIN(gpio)),
 +              (value << PORTEXP_IO_TO_PIN(gpio)));
 +
 +      if (ret)
 +              return ret;
 +
 +      return 0;
 +}
 +
 +static iomux_v3_cfg_t const eimnor_pads[] = {
 +      MX6_PAD_EIM_D16__EIM_DATA16     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D17__EIM_DATA17     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D18__EIM_DATA18     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D19__EIM_DATA19     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D20__EIM_DATA20     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D21__EIM_DATA21     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D22__EIM_DATA22     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D23__EIM_DATA23     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D24__EIM_DATA24     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D25__EIM_DATA25     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D26__EIM_DATA26     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D27__EIM_DATA27     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D28__EIM_DATA28     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D29__EIM_DATA29     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D30__EIM_DATA30     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_D31__EIM_DATA31     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA0__EIM_AD00       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA1__EIM_AD01       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA2__EIM_AD02       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA3__EIM_AD03       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA4__EIM_AD04       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA5__EIM_AD05       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA6__EIM_AD06       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA7__EIM_AD07       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA8__EIM_AD08       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA9__EIM_AD09       | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA10__EIM_AD10      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA11__EIM_AD11      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL) ,
 +      MX6_PAD_EIM_DA12__EIM_AD12      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA13__EIM_AD13      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA14__EIM_AD14      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_DA15__EIM_AD15      | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A16__EIM_ADDR16     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A17__EIM_ADDR17     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A18__EIM_ADDR18     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A19__EIM_ADDR19     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A20__EIM_ADDR20     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A21__EIM_ADDR21     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A22__EIM_ADDR22     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
 +      MX6_PAD_EIM_A23__EIM_ADDR23     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
-       MX6_PAD_EIM_OE__EIM_OE_B        | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_EIM_RW__EIM_RW          | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_EIM_CS0__EIM_CS0_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_EIM_OE__EIM_OE_B,
++      MX6_PAD_EIM_RW__EIM_RW,
++      MX6_PAD_EIM_CS0__EIM_CS0_B,
  };
  
 +static void eimnor_cs_setup(void)
 +{
 +      struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
 +
 +      writel(0x00020181, &weim_regs->cs0gcr1);
 +      writel(0x00000001, &weim_regs->cs0gcr2);
 +      writel(0x0a020000, &weim_regs->cs0rcr1);
 +      writel(0x0000c000, &weim_regs->cs0rcr2);
 +      writel(0x0804a240, &weim_regs->cs0wcr1);
 +      writel(0x00000120, &weim_regs->wcr);
 +
 +      set_chipselect_size(CS0_128);
 +}
 +
 +static void setup_iomux_eimnor(void)
 +{
 +      imx_iomux_v3_setup_multiple_pads(eimnor_pads, ARRAY_SIZE(eimnor_pads));
 +
 +      gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
 +
 +      eimnor_cs_setup();
 +}
 +
  static void setup_iomux_enet(void)
  {
        imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
  }
  
 -iomux_v3_cfg_t const usdhc3_pads[] = {
 -      MX6_PAD_SD3_CLK__USDHC3_CLK     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_CMD__USDHC3_CMD     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT0__USDHC3_DAT0   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT1__USDHC3_DAT1   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT2__USDHC3_DAT2   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT3__USDHC3_DAT3   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT4__USDHC3_DAT4   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT5__USDHC3_DAT5   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT6__USDHC3_DAT6   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT7__USDHC3_DAT7   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_GPIO_18__USDHC3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_CS2__GPIO_6_15,
 +static iomux_v3_cfg_t const usdhc3_pads[] = {
 +      MX6_PAD_SD3_CLK__SD3_CLK        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CMD__SD3_CMD        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT0__SD3_DATA0     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT1__SD3_DATA1     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT2__SD3_DATA2     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT3__SD3_DATA3     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT4__SD3_DATA4     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT5__SD3_DATA5     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT6__SD3_DATA6     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT7__SD3_DATA7     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_CS2__GPIO6_IO15   | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_NANDF_CS2__GPIO6_IO15,
  };
  
  static void setup_iomux_uart(void)
  }
  
  #ifdef CONFIG_FSL_ESDHC
 -struct fsl_esdhc_cfg usdhc_cfg[1] = {
 +static struct fsl_esdhc_cfg usdhc_cfg[1] = {
        {USDHC3_BASE_ADDR},
  };
  
@@@ -284,63 -157,6 +284,63 @@@ int board_mmc_init(bd_t *bis
  }
  #endif
  
 +#ifdef CONFIG_NAND_MXS
 +static iomux_v3_cfg_t gpmi_pads[] = {
 +      MX6_PAD_NANDF_CLE__NAND_CLE             | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_ALE__NAND_ALE             | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_WP_B__NAND_WP_B   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0),
 +      MX6_PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_SD4_CMD__NAND_RE_B              | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_SD4_CLK__NAND_WE_B              | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
 +      MX6_PAD_SD4_DAT0__NAND_DQS              | MUX_PAD_CTRL(GPMI_PAD_CTRL1),
 +};
 +
 +static void setup_gpmi_nand(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +
 +      /* config gpmi nand iomux */
 +      imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads));
 +
 +      /* gate ENFC_CLK_ROOT clock first,before clk source switch */
 +      clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
 +      clrbits_le32(&mxc_ccm->CCGR4,
 +              MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
 +
 +      /* config gpmi and bch clock to 100 MHz */
 +      clrsetbits_le32(&mxc_ccm->cs2cdr,
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
 +                      MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
 +
 +      /* enable ENFC_CLK_ROOT clock */
 +      setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
 +
 +      /* enable gpmi and bch clock gating */
 +      setbits_le32(&mxc_ccm->CCGR4,
 +                   MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
 +                   MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
 +                   MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
 +
 +      /* enable apbh clock gating */
 +      setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
 +}
 +#endif
 +
  int mx6_rgmii_rework(struct phy_device *phydev)
  {
        unsigned short val;
@@@ -376,9 -192,15 +376,9 @@@ int board_phy_config(struct phy_device 
  
  int board_eth_init(bd_t *bis)
  {
 -      int ret;
 -
        setup_iomux_enet();
  
 -      ret = cpu_eth_init(bis);
 -      if (ret)
 -              printf("FEC MXC: %s:failed\n", __func__);
 -
 -      return 0;
 +      return cpu_eth_init(bis);
  }
  
  #define BOARD_REV_B  0x200
@@@ -418,69 -240,9 +418,69 @@@ u32 get_board_rev(void
        return (get_cpu_rev() & ~(0xF << 8)) | rev;
  }
  
 +#if defined(CONFIG_VIDEO_IPUV3)
 +static void do_enable_hdmi(struct display_info_t const *dev)
 +{
 +      imx_enable_hdmi_phy();
 +}
 +
 +struct display_info_t const displays[] = {{
 +      .bus    = -1,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = detect_hdmi,
 +      .enable = do_enable_hdmi,
 +      .mode   = {
 +              .name           = "HDMI",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 768,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED,
 +} } };
 +size_t display_count = ARRAY_SIZE(displays);
 +
 +static void setup_display(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      int reg;
 +
 +      enable_ipu_clock();
 +      imx_setup_hdmi();
 +
 +      reg = readl(&mxc_ccm->chsccdr);
 +      reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 +              << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 +      writel(reg, &mxc_ccm->chsccdr);
 +}
 +#endif /* CONFIG_VIDEO_IPUV3 */
 +
 +/*
 + * Do not overwrite the console
 + * Use always serial for U-Boot console
 + */
 +int overwrite_console(void)
 +{
 +      return 1;
 +}
 +
  int board_early_init_f(void)
  {
        setup_iomux_uart();
 +#ifdef CONFIG_VIDEO_IPUV3
 +      setup_display();
 +#endif
 +
 +#ifdef CONFIG_NAND_MXS
 +      setup_gpmi_nand();
 +#endif
  
        return 0;
  }
@@@ -495,31 -257,11 +495,31 @@@ int board_init(void
        /* I2C 3 Steer */
        gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
        imx_iomux_v3_setup_multiple_pads(i2c3_pads, ARRAY_SIZE(i2c3_pads));
 +#ifndef CONFIG_SYS_FLASH_CFI
        setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
 -
 +#endif
        gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
        imx_iomux_v3_setup_multiple_pads(port_exp, ARRAY_SIZE(port_exp));
  
 +      setup_iomux_eimnor();
 +      return 0;
 +}
 +
 +#ifdef CONFIG_MXC_SPI
 +int board_spi_cs_gpio(unsigned bus, unsigned cs)
 +{
 +      return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
 +}
 +#endif
 +
 +int power_init_board(void)
 +{
 +      struct pmic *p;
 +
 +      p = pfuze_common_init(I2C_PMIC);
 +      if (!p)
 +              return -ENODEV;
 +
        return 0;
  }
  
@@@ -559,57 -301,3 +559,57 @@@ int checkboard(void
  
        return 0;
  }
-       MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
 +
 +#ifdef CONFIG_USB_EHCI_MX6
 +#define USB_HOST1_PWR     PORTEXP_IO_NR(0x32, 7)
 +#define USB_OTG_PWR       PORTEXP_IO_NR(0x34, 1)
 +
 +iomux_v3_cfg_t const usb_otg_pads[] = {
++      MX6_PAD_ENET_RX_ER__USB_OTG_ID,
 +};
 +
 +int board_ehci_hcd_init(int port)
 +{
 +      switch (port) {
 +      case 0:
 +              imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 +                      ARRAY_SIZE(usb_otg_pads));
 +
 +              /*
 +                * Set daisy chain for otg_pin_id on 6q.
 +               *  For 6dl, this bit is reserved.
 +               */
 +              imx_iomux_set_gpr_register(1, 13, 1, 0);
 +              break;
 +      case 1:
 +              break;
 +      default:
 +              printf("MXC USB port %d not yet supported\n", port);
 +              return -EINVAL;
 +      }
 +      return 0;
 +}
 +
 +int board_ehci_power(int port, int on)
 +{
 +      switch (port) {
 +      case 0:
 +              if (on)
 +                      port_exp_direction_output(USB_OTG_PWR, 1);
 +              else
 +                      port_exp_direction_output(USB_OTG_PWR, 0);
 +              break;
 +      case 1:
 +              if (on)
 +                      port_exp_direction_output(USB_HOST1_PWR, 1);
 +              else
 +                      port_exp_direction_output(USB_HOST1_PWR, 0);
 +              break;
 +      default:
 +              printf("MXC USB port %d not yet supported\n", port);
 +              return -EINVAL;
 +      }
 +
 +      return 0;
 +}
 +#endif
index 0000000000000000000000000000000000000000,02dc289e0e8414882bd0742763e637c9e8b02a2d..91ac10dc701d133c1c9f163f5bd3488400297db3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,832 +1,832 @@@
 -      struct iomuxc_base_regs *const iomuxc_regs
 -              = (struct iomuxc_base_regs *) IOMUXC_BASE_ADDR;
+ /*
+  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+  *
+  * SPDX-License-Identifier:   GPL-2.0+ 
+  */
+ #include <common.h>
+ #include <asm/io.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/iomux.h>
+ #include <asm/arch/mx6q_pins.h>
+ #include <asm/errno.h>
+ #include <asm/gpio.h>
+ #include <asm/imx-common/iomux-v3.h>
+ #include <asm/imx-common/mxc_i2c.h>
+ #include <asm/imx-common/boot_mode.h>
+ #include <mmc.h>
+ #include <fsl_esdhc.h>
+ #include <malloc.h>
+ #include <micrel.h>
+ #include <miiphy.h>
+ #include <netdev.h>
+ #include <linux/fb.h>
+ #include <ipu_pixfmt.h>
+ #include <asm/arch/crm_regs.h>
+ #include <asm/arch/mxc_hdmi.h>
+ #include <i2c.h>
+ DECLARE_GLOBAL_DATA_PTR;
+ #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                 \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
+       PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+ #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                  \
+       PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
+       PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+ #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                 \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+ #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED |               \
+       PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+ #define BUTTON_PAD_CTRL (PAD_CTL_PUS_100K_UP |                        \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+ #define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
+       PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+ int dram_init(void)
+ {
+       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+       return 0;
+ }
+ iomux_v3_cfg_t const uart1_pads[] = {
+       MX6_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+ };
+ iomux_v3_cfg_t const uart2_pads[] = {
+       MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+ };
+ #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
+ /* I2C1, SGTL5000 */
+ struct i2c_pads_info i2c_pad_info0 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
+               .gpio_mode = MX6_PAD_EIM_D21__GPIO_3_21 | PC,
+               .gp = IMX_GPIO_NR(3, 21)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
+               .gpio_mode = MX6_PAD_EIM_D28__GPIO_3_28 | PC,
+               .gp = IMX_GPIO_NR(3, 28)
+       }
+ };
+ /* I2C2 Camera, MIPI */
+ struct i2c_pads_info i2c_pad_info1 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
+               .gpio_mode = MX6_PAD_KEY_COL3__GPIO_4_12 | PC,
+               .gp = IMX_GPIO_NR(4, 12)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
+               .gpio_mode = MX6_PAD_KEY_ROW3__GPIO_4_13 | PC,
+               .gp = IMX_GPIO_NR(4, 13)
+       }
+ };
+ /* I2C3, J15 - RGB connector */
+ struct i2c_pads_info i2c_pad_info2 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
+               .gpio_mode = MX6_PAD_GPIO_5__GPIO_1_5 | PC,
+               .gp = IMX_GPIO_NR(1, 5)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC,
+               .gpio_mode = MX6_PAD_GPIO_16__GPIO_7_11 | PC,
+               .gp = IMX_GPIO_NR(7, 11)
+       }
+ };
+ iomux_v3_cfg_t const usdhc3_pads[] = {
+       MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
+ };
+ iomux_v3_cfg_t const usdhc4_pads[] = {
+       MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
+ };
+ iomux_v3_cfg_t const enet_pads1[] = {
+       MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       /* pin 35 - 1 (PHY_AD2) on reset */
+       MX6_PAD_RGMII_RXC__GPIO_6_30,
+       /* pin 32 - 1 - (MODE0) all */
+       MX6_PAD_RGMII_RD0__GPIO_6_25,
+       /* pin 31 - 1 - (MODE1) all */
+       MX6_PAD_RGMII_RD1__GPIO_6_27,
+       /* pin 28 - 1 - (MODE2) all */
+       MX6_PAD_RGMII_RD2__GPIO_6_28,
+       /* pin 27 - 1 - (MODE3) all */
+       MX6_PAD_RGMII_RD3__GPIO_6_29,
+       /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+       MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
+       /* pin 42 PHY nRST */
+       MX6_PAD_EIM_D23__GPIO_3_23,
+ };
+ iomux_v3_cfg_t const enet_pads2[] = {
+       MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ };
+ /* Button assignments for J14 */
+ static iomux_v3_cfg_t const button_pads[] = {
+       /* Menu */
+       MX6_PAD_NANDF_D1__GPIO_2_1      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Back */
+       MX6_PAD_NANDF_D2__GPIO_2_2      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Labelled Search (mapped to Power under Android) */
+       MX6_PAD_NANDF_D3__GPIO_2_3      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Home */
+       MX6_PAD_NANDF_D4__GPIO_2_4      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Volume Down */
+       MX6_PAD_GPIO_19__GPIO_4_5       | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Volume Up */
+       MX6_PAD_GPIO_18__GPIO_7_13      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+ };
+ static void setup_iomux_enet(void)
+ {
+       gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
+       gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
+       imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
+       gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
+       /* Need delay 10ms according to KSZ9021 spec */
+       udelay(1000 * 10);
+       gpio_set_value(IMX_GPIO_NR(3, 23), 1);
+       imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+ }
+ iomux_v3_cfg_t const usb_pads[] = {
+       MX6_PAD_GPIO_17__GPIO_7_12,
+ };
+ static void setup_iomux_uart(void)
+ {
+       imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+       imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+ }
+ #ifdef CONFIG_USB_EHCI_MX6
+ int board_ehci_hcd_init(int port)
+ {
+       imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+       /* Reset USB hub */
+       gpio_direction_output(IMX_GPIO_NR(7, 12), 0);
+       mdelay(2);
+       gpio_set_value(IMX_GPIO_NR(7, 12), 1);
+       return 0;
+ }
+ #endif
+ #ifdef CONFIG_FSL_ESDHC
+ struct fsl_esdhc_cfg usdhc_cfg[2] = {
+       {USDHC3_BASE_ADDR},
+       {USDHC4_BASE_ADDR},
+ };
+ int board_mmc_getcd(struct mmc *mmc)
+ {
+       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       int ret;
+       if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
+               gpio_direction_input(IMX_GPIO_NR(7, 0));
+               ret = !gpio_get_value(IMX_GPIO_NR(7, 0));
+       } else {
+               gpio_direction_input(IMX_GPIO_NR(2, 6));
+               ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
+       }
+       return ret;
+ }
+ int board_mmc_init(bd_t *bis)
+ {
+       s32 status = 0;
+       u32 index = 0;
+       usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+       usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+       usdhc_cfg[0].max_bus_width = 4;
+       usdhc_cfg[1].max_bus_width = 4;
+       for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
+               switch (index) {
+               case 0:
+                       imx_iomux_v3_setup_multiple_pads(
+                               usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+                       break;
+               case 1:
+                       imx_iomux_v3_setup_multiple_pads(
+                               usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+                       break;
+               default:
+                       printf("Warning: you configured more USDHC controllers"
+                              "(%d) then supported by the board (%d)\n",
+                              index + 1, CONFIG_SYS_FSL_USDHC_NUM);
+                       return status;
+               }
+               status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
+       }
+       return status;
+ }
+ #endif
+ #ifdef CONFIG_MXC_SPI
+ iomux_v3_cfg_t const ecspi1_pads[] = {
+       /* SS1 */
+       MX6_PAD_EIM_D19__GPIO_3_19   | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
+ };
+ void setup_spi(void)
+ {
+       imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
+                                        ARRAY_SIZE(ecspi1_pads));
+ }
+ #endif
+ int board_phy_config(struct phy_device *phydev)
+ {
+       /* min rx data delay */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
+       /* min tx data delay */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
+       /* max rx/tx clock delay, min rx/tx control */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
+       if (phydev->drv->config)
+               phydev->drv->config(phydev);
+       return 0;
+ }
+ int board_eth_init(bd_t *bis)
+ {
+       uint32_t base = IMX_FEC_BASE;
+       struct mii_dev *bus = NULL;
+       struct phy_device *phydev = NULL;
+       int ret;
+       setup_iomux_enet();
+ #ifdef CONFIG_FEC_MXC
+       bus = fec_get_miibus(base, -1);
+       if (!bus)
+               return 0;
+       /* scan phy 4,5,6,7 */
+       phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
+       if (!phydev) {
+               free(bus);
+               return 0;
+       }
+       printf("using phy at %d\n", phydev->addr);
+       ret  = fec_probe(bis, -1, base, bus, phydev);
+       if (ret) {
+               printf("FEC MXC: %s:failed\n", __func__);
+               free(phydev);
+               free(bus);
+       }
+ #endif
+       return 0;
+ }
+ static void setup_buttons(void)
+ {
+       imx_iomux_v3_setup_multiple_pads(button_pads,
+                                        ARRAY_SIZE(button_pads));
+ }
+ #ifdef CONFIG_CMD_SATA
+ int setup_sata(void)
+ {
++      struct iomuxc *const iomuxc_regs = (void *)IOMUXC_BASE_ADDR;
+       int ret = enable_sata_clock();
++
+       if (ret)
+               return ret;
+       clrsetbits_le32(&iomuxc_regs->gpr[13],
+                       IOMUXC_GPR13_SATA_MASK,
+                       IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB
+                       |IOMUXC_GPR13_SATA_PHY_7_SATA2M
+                       |IOMUXC_GPR13_SATA_SPEED_3G
+                       |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT)
+                       |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED
+                       |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16
+                       |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB
+                       |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V
+                       |IOMUXC_GPR13_SATA_PHY_1_SLOW);
+       return 0;
+ }
+ #endif
+ #if defined(CONFIG_VIDEO_IPUV3)
+ static iomux_v3_cfg_t const backlight_pads[] = {
+       /* Backlight on RGB connector: J15 */
+       MX6_PAD_SD1_DAT3__GPIO_1_21,
+ #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
+       /* Backlight on LVDS connector: J6 */
+       MX6_PAD_SD1_CMD__GPIO_1_18,
+ #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
+ };
+ static iomux_v3_cfg_t const rgb_pads[] = {
+       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+       MX6_PAD_DI0_PIN4__GPIO_4_20,
+       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+ };
+ struct display_info_t {
+       int     bus;
+       int     addr;
+       int     pixfmt;
+       int     (*detect)(struct display_info_t const *dev);
+       void    (*enable)(struct display_info_t const *dev);
+       struct  fb_videomode mode;
+ };
+ static int detect_hdmi(struct display_info_t const *dev)
+ {
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+       return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
+ }
+ static void enable_hdmi(struct display_info_t const *dev)
+ {
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+       u8 reg;
+       printf("%s: setup HDMI monitor\n", __func__);
+       reg = readb(&hdmi->phy_conf0);
+       reg |= HDMI_PHY_CONF0_PDZ_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+       udelay(3000);
+       reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+       udelay(3000);
+       reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+       writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
+ }
+ static int detect_i2c(struct display_info_t const *dev)
+ {
+       return ((0 == i2c_set_bus_num(dev->bus))
+               &&
+               (0 == i2c_probe(dev->addr)));
+ }
+ static void enable_lvds(struct display_info_t const *dev)
+ {
+       struct iomuxc *iomux = (struct iomuxc *)
+                               IOMUXC_BASE_ADDR;
+       u32 reg = readl(&iomux->gpr[2]);
+       reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
+       writel(reg, &iomux->gpr[2]);
+       gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
+ }
+ static void enable_rgb(struct display_info_t const *dev)
+ {
+       imx_iomux_v3_setup_multiple_pads(
+               rgb_pads,
+                ARRAY_SIZE(rgb_pads));
+       gpio_direction_output(RGB_BACKLIGHT_GP, 1);
+ }
+ static struct display_info_t const displays[] = {{
+       .bus    = -1,
+       .addr   = 0,
+       .pixfmt = IPU_PIX_FMT_RGB24,
+       .detect = detect_hdmi,
+       .enable = enable_hdmi,
+       .mode   = {
+               .name           = "HDMI",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+ } }, {
+       .bus    = 2,
+       .addr   = 0x4,
+       .pixfmt = IPU_PIX_FMT_LVDS666,
+       .detect = detect_i2c,
+       .enable = enable_lvds,
+       .mode   = {
+               .name           = "Hannstar-XGA",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+ } }, {
+       .bus    = 2,
+       .addr   = 0x38,
+       .pixfmt = IPU_PIX_FMT_LVDS666,
+       .detect = detect_i2c,
+       .enable = enable_lvds,
+       .mode   = {
+               .name           = "wsvga-lvds",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 600,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+ } }, {
+       .bus    = 2,
+       .addr   = 0x48,
+       .pixfmt = IPU_PIX_FMT_RGB666,
+       .detect = detect_i2c,
+       .enable = enable_rgb,
+       .mode   = {
+               .name           = "wvga-rgb",
+               .refresh        = 57,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = 37037,
+               .left_margin    = 40,
+               .right_margin   = 60,
+               .upper_margin   = 10,
+               .lower_margin   = 10,
+               .hsync_len      = 20,
+               .vsync_len      = 10,
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED
+ } } };
+ int board_video_skip(void)
+ {
+       int i;
+       int ret;
+       char const *panel = getenv("panel");
+       if (!panel) {
+               for (i = 0; i < ARRAY_SIZE(displays); i++) {
+                       struct display_info_t const *dev = displays+i;
+                       if (dev->detect(dev)) {
+                               panel = dev->mode.name;
+                               printf("auto-detected panel %s\n", panel);
+                               break;
+                       }
+               }
+               if (!panel) {
+                       panel = displays[0].mode.name;
+                       printf("No panel detected: default to %s\n", panel);
+               }
+       } else {
+               for (i = 0; i < ARRAY_SIZE(displays); i++) {
+                       if (!strcmp(panel, displays[i].mode.name))
+                               break;
+               }
+       }
+       if (i < ARRAY_SIZE(displays)) {
+               ret = ipuv3_fb_init(&displays[i].mode, 0,
+                                   displays[i].pixfmt);
+               if (!ret) {
+                       displays[i].enable(displays+i);
+                       printf("Display: %s (%ux%u)\n",
+                              displays[i].mode.name,
+                              displays[i].mode.xres,
+                              displays[i].mode.yres);
+               } else
+                       printf("LCD %s cannot be configured: %d\n",
+                              displays[i].mode.name, ret);
+       } else {
+               printf("unsupported panel %s\n", panel);
+               ret = -EINVAL;
+       }
+       return (0 != ret);
+ }
+ static void setup_display(void)
+ {
+       struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+       struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+       int reg;
+       /* Turn on LDB0,IPU,IPU DI0 clocks */
+       reg = __raw_readl(&mxc_ccm->CCGR3);
+       reg |=   MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
+               |MXC_CCM_CCGR3_LDB_DI0_MASK;
+       writel(reg, &mxc_ccm->CCGR3);
+       /* Turn on HDMI PHY clock */
+       reg = __raw_readl(&mxc_ccm->CCGR2);
+       reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
+              |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
+       writel(reg, &mxc_ccm->CCGR2);
+       /* clear HDMI PHY reset */
+       writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
+       /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
+       writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
+       writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
+       /* set LDB0, LDB1 clk select to 011/011 */
+       reg = readl(&mxc_ccm->cs2cdr);
+       reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
+                |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+       reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
+             |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+       writel(reg, &mxc_ccm->cs2cdr);
+       reg = readl(&mxc_ccm->cscmr2);
+       reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+       writel(reg, &mxc_ccm->cscmr2);
+       reg = readl(&mxc_ccm->chsccdr);
+       reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
+               |MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
+               |MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
+       reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
+             |(CHSCCDR_PODF_DIVIDE_BY_3
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
+             |(CHSCCDR_IPU_PRE_CLK_540M_PFD
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+       writel(reg, &mxc_ccm->chsccdr);
+       reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+            |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
+            |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+            |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
+            |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
+            |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+            |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
+            |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
+            |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
+       writel(reg, &iomux->gpr[2]);
+       reg = readl(&iomux->gpr[3]);
+       reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
+           | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
+              <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
+       writel(reg, &iomux->gpr[3]);
+       /* backlights off until needed */
+       imx_iomux_v3_setup_multiple_pads(backlight_pads,
+                                        ARRAY_SIZE(backlight_pads));
+       gpio_direction_input(LVDS_BACKLIGHT_GP);
+       gpio_direction_input(RGB_BACKLIGHT_GP);
+ }
+ #endif
+ int board_early_init_f(void)
+ {
+       setup_iomux_uart();
+       setup_buttons();
+ #if defined(CONFIG_VIDEO_IPUV3)
+       setup_display();
+ #endif
+       return 0;
+ }
+ /*
+  * Do not overwrite the console
+  * Use always serial for U-Boot console
+  */
+ int overwrite_console(void)
+ {
+       return 1;
+ }
+ int board_init(void)
+ {
+       /* address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+ #ifdef CONFIG_MXC_SPI
+       setup_spi();
+ #endif
+       setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
+       setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+       setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+ #ifdef CONFIG_CMD_SATA
+       setup_sata();
+ #endif
+       return 0;
+ }
+ int checkboard(void)
+ {
+       puts("Board: MX6Q-Sabre Lite\n");
+       return 0;
+ }
+ struct button_key {
+       char const      *name;
+       unsigned        gpnum;
+       char            ident;
+ };
+ static struct button_key const buttons[] = {
+       {"back",        IMX_GPIO_NR(2, 2),      'B'},
+       {"home",        IMX_GPIO_NR(2, 4),      'H'},
+       {"menu",        IMX_GPIO_NR(2, 1),      'M'},
+       {"search",      IMX_GPIO_NR(2, 3),      'S'},
+       {"volup",       IMX_GPIO_NR(7, 13),     'V'},
+       {"voldown",     IMX_GPIO_NR(4, 5),      'v'},
+ };
+ /*
+  * generate a null-terminated string containing the buttons pressed
+  * returns number of keys pressed
+  */
+ static int read_keys(char *buf)
+ {
+       int i, numpressed = 0;
+       for (i = 0; i < ARRAY_SIZE(buttons); i++) {
+               if (!gpio_get_value(buttons[i].gpnum))
+                       buf[numpressed++] = buttons[i].ident;
+       }
+       buf[numpressed] = '\0';
+       return numpressed;
+ }
+ static int do_kbd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+ {
+       char envvalue[ARRAY_SIZE(buttons)+1];
+       int numpressed = read_keys(envvalue);
+       setenv("keybd", envvalue);
+       return numpressed == 0;
+ }
+ U_BOOT_CMD(
+       kbd, 1, 1, do_kbd,
+       "Tests for keypresses, sets 'keybd' environment variable",
+       "Returns 0 (true) to shell if key is pressed."
+ );
+ #ifdef CONFIG_PREBOOT
+ static char const kbd_magic_prefix[] = "key_magic";
+ static char const kbd_command_prefix[] = "key_cmd";
+ static void preboot_keys(void)
+ {
+       int numpressed;
+       char keypress[ARRAY_SIZE(buttons)+1];
+       numpressed = read_keys(keypress);
+       if (numpressed) {
+               char *kbd_magic_keys = getenv("magic_keys");
+               char *suffix;
+               /*
+                * loop over all magic keys
+                */
+               for (suffix = kbd_magic_keys; *suffix; ++suffix) {
+                       char *keys;
+                       char magic[sizeof(kbd_magic_prefix) + 1];
+                       sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
+                       keys = getenv(magic);
+                       if (keys) {
+                               if (!strcmp(keys, keypress))
+                                       break;
+                       }
+               }
+               if (*suffix) {
+                       char cmd_name[sizeof(kbd_command_prefix) + 1];
+                       char *cmd;
+                       sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
+                       cmd = getenv(cmd_name);
+                       if (cmd) {
+                               setenv("preboot", cmd);
+                               return;
+                       }
+               }
+       }
+ }
+ #endif
+ #ifdef CONFIG_CMD_BMODE
+ static const struct boot_mode board_boot_modes[] = {
+       /* 4 bit bus width */
+       {"mmc0",        MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+       {"mmc1",        MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
+       {NULL,          0},
+ };
+ #endif
+ int misc_init_r(void)
+ {
+ #ifdef CONFIG_PREBOOT
+       preboot_keys();
+ #endif
+ #ifdef CONFIG_CMD_BMODE
+       add_board_boot_modes(board_boot_modes);
+ #endif
+       return 0;
+ }
index 2f7198d3bfdfc0b438ec185973d62dcb3dc45156,288da292d5b2538d8183822a920aee811f250af3..215faa98fac2247cd268f471f29fabf605a3329c
  #include <asm/arch/mx6-pins.h>
  #include <asm/errno.h>
  #include <asm/gpio.h>
 +#include <asm/imx-common/mxc_i2c.h>
  #include <asm/imx-common/iomux-v3.h>
  #include <asm/imx-common/boot_mode.h>
 +#include <asm/imx-common/video.h>
  #include <mmc.h>
  #include <fsl_esdhc.h>
  #include <miiphy.h>
  #include <netdev.h>
 +#include <asm/arch/mxc_hdmi.h>
 +#include <asm/arch/crm_regs.h>
 +#include <asm/io.h>
 +#include <asm/arch/sys_proto.h>
 +#include <i2c.h>
 +#include <power/pmic.h>
 +#include <power/pfuze100_pmic.h>
 +#include "../common/pfuze.h"
 +#include <asm/arch/mx6-ddr.h>
 +#include <usb.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
  #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                 \
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  
 +#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
 +                    PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
 +
 +#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
 +      PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
 +      PAD_CTL_ODE | PAD_CTL_SRE_FAST)
 +
 +#define I2C_PMIC      1
 +
 +#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
 +
 +#define DISP0_PWR_EN  IMX_GPIO_NR(1, 21)
 +
  int dram_init(void)
  {
 -      gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
 -
 +      gd->ram_size = imx_ddr_size();
        return 0;
  }
  
 -iomux_v3_cfg_t const uart1_pads[] = {
 -      MX6_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +static iomux_v3_cfg_t const uart1_pads[] = {
 +      MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
 -iomux_v3_cfg_t const enet_pads[] = {
 +static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TXC__RGMII_TXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD0__RGMII_TD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD1__RGMII_TD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD2__RGMII_TD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD3__RGMII_TD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RXC__RGMII_RXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD0__RGMII_RD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD1__RGMII_RD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD2__RGMII_RD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_ENET_CRS_DV__GPIO1_IO25         | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_ENET_CRS_DV__GPIO_1_25,
++      MX6_PAD_ENET_CRS_DV__GPIO1_IO25,
  };
  
  static void setup_iomux_enet(void)
        gpio_set_value(IMX_GPIO_NR(1, 25), 1);
  }
  
 -iomux_v3_cfg_t const usdhc2_pads[] = {
 -      MX6_PAD_SD2_CLK__USDHC2_CLK     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_CMD__USDHC2_CMD     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT0__USDHC2_DAT0   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT1__USDHC2_DAT1   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT2__USDHC2_DAT2   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT3__USDHC2_DAT3   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D4__USDHC2_DAT4   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D5__USDHC2_DAT5   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D6__USDHC2_DAT6   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D7__USDHC2_DAT7   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D2__GPIO_2_2, /* CD */
 +static iomux_v3_cfg_t const usdhc2_pads[] = {
 +      MX6_PAD_SD2_CLK__SD2_CLK        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_CMD__SD2_CMD        | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT0__SD2_DATA0     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT1__SD2_DATA1     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT2__SD2_DATA2     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD2_DAT3__SD2_DATA3     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_NANDF_D4__SD2_DATA4     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_NANDF_D5__SD2_DATA5     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_NANDF_D6__SD2_DATA6     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_NANDF_D7__SD2_DATA7     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D2__GPIO2_IO02    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_NANDF_D2__GPIO2_IO02, /* CD */
 +};
 +
 +static iomux_v3_cfg_t const usdhc3_pads[] = {
 +      MX6_PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
++      MX6_PAD_NANDF_D0__GPIO2_IO00, /* CD */
 +};
 +
 +static iomux_v3_cfg_t const usdhc4_pads[] = {
 +      MX6_PAD_SD4_CLK__SD4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_CMD__SD4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  };
  
 -iomux_v3_cfg_t const usdhc3_pads[] = {
 -      MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_NANDF_D0__GPIO_2_0, /* CD */
 +static iomux_v3_cfg_t const ecspi1_pads[] = {
 +      MX6_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
 +      MX6_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
 +      MX6_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
-       MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_KEY_ROW1__GPIO4_IO09,
  };
  
 -iomux_v3_cfg_t const usdhc4_pads[] = {
 -      MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +static iomux_v3_cfg_t const rgb_pads[] = {
-       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
++      MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
++      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
++      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
++      MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04,
++      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
++      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
++      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
++      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
++      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
++      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
++      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
++      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
++      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
++      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
++      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
++      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
++      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
++      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
++      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
++      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
++      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
++      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
++      MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
++      MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
++      MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
++      MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
++      MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
++      MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
++      MX6_PAD_SD1_DAT3__GPIO1_IO21,
 +};
 +
 +static void enable_rgb(struct display_info_t const *dev)
 +{
 +      imx_iomux_v3_setup_multiple_pads(rgb_pads, ARRAY_SIZE(rgb_pads));
 +      gpio_direction_output(DISP0_PWR_EN, 1);
 +}
 +
 +static struct i2c_pads_info i2c_pad_info1 = {
 +      .scl = {
 +              .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
 +              .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
 +              .gp = IMX_GPIO_NR(4, 12)
 +      },
 +      .sda = {
 +              .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
 +              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
 +              .gp = IMX_GPIO_NR(4, 13)
 +      }
 +};
 +
 +static void setup_spi(void)
 +{
 +      imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
 +}
 +
 +iomux_v3_cfg_t const pcie_pads[] = {
-       MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),        /* POWER */
-       MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),        /* RESET */
++      MX6_PAD_EIM_D19__GPIO3_IO19,    /* POWER */
++      MX6_PAD_GPIO_17__GPIO7_IO12,    /* RESET */
 +};
 +
 +static void setup_pcie(void)
 +{
 +      imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads));
 +}
 +
 +iomux_v3_cfg_t const di0_pads[] = {
 +      MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,        /* DISP0_CLK */
 +      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,               /* DISP0_HSYNC */
 +      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,               /* DISP0_VSYNC */
  };
  
  static void setup_iomux_uart(void)
@@@ -256,8 -152,7 +256,8 @@@ int board_mmc_getcd(struct mmc *mmc
  
  int board_mmc_init(bd_t *bis)
  {
 -      s32 status = 0;
 +#ifndef CONFIG_SPL_BUILD
 +      int ret;
        int i;
  
        /*
                        printf("Warning: you configured more USDHC controllers"
                               "(%d) then supported by the board (%d)\n",
                               i + 1, CONFIG_SYS_FSL_USDHC_NUM);
 -                      return status;
 +                      return -EINVAL;
                }
  
 -              status |= fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 +              ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 +              if (ret)
 +                      return ret;
 +      }
 +
 +      return 0;
 +#else
 +      struct src *psrc = (struct src *)SRC_BASE_ADDR;
 +      unsigned reg = readl(&psrc->sbmr1) >> 11;
 +      /*
 +       * Upon reading BOOT_CFG register the following map is done:
 +       * Bit 11 and 12 of BOOT_CFG register can determine the current
 +       * mmc port
 +       * 0x1                  SD1
 +       * 0x2                  SD2
 +       * 0x3                  SD4
 +       */
 +
 +      switch (reg & 0x3) {
 +      case 0x1:
 +              imx_iomux_v3_setup_multiple_pads(
 +                      usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
 +              usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
 +              usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
 +              gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 +              break;
 +      case 0x2:
 +              imx_iomux_v3_setup_multiple_pads(
 +                      usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
 +              usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
 +              usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 +              gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 +              break;
 +      case 0x3:
 +              imx_iomux_v3_setup_multiple_pads(
 +                      usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
 +              usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
 +              usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 +              gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
 +              break;
        }
  
 -      return status;
 +      return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
 +#endif
  }
  #endif
  
@@@ -373,240 -228,22 +373,240 @@@ int board_phy_config(struct phy_device 
        return 0;
  }
  
 -int board_eth_init(bd_t *bis)
 +#if defined(CONFIG_VIDEO_IPUV3)
 +static void disable_lvds(struct display_info_t const *dev)
  {
 -      int ret;
 +      struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 +
 +      int reg = readl(&iomux->gpr[2]);
 +
 +      reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
 +               IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
 +
 +      writel(reg, &iomux->gpr[2]);
 +}
 +
 +static void do_enable_hdmi(struct display_info_t const *dev)
 +{
 +      disable_lvds(dev);
 +      imx_enable_hdmi_phy();
 +}
 +
 +static void enable_lvds(struct display_info_t const *dev)
 +{
 +      struct iomuxc *iomux = (struct iomuxc *)
 +                              IOMUXC_BASE_ADDR;
 +      u32 reg = readl(&iomux->gpr[2]);
 +      reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
 +             IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT;
 +      writel(reg, &iomux->gpr[2]);
 +}
  
 +struct display_info_t const displays[] = {{
 +      .bus    = -1,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB666,
 +      .detect = NULL,
 +      .enable = enable_lvds,
 +      .mode   = {
 +              .name           = "Hannstar-XGA",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 768,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = -1,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = detect_hdmi,
 +      .enable = do_enable_hdmi,
 +      .mode   = {
 +              .name           = "HDMI",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 768,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 0,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = NULL,
 +      .enable = enable_rgb,
 +      .mode   = {
 +              .name           = "SEIKO-WVGA",
 +              .refresh        = 60,
 +              .xres           = 800,
 +              .yres           = 480,
 +              .pixclock       = 29850,
 +              .left_margin    = 89,
 +              .right_margin   = 164,
 +              .upper_margin   = 23,
 +              .lower_margin   = 10,
 +              .hsync_len      = 10,
 +              .vsync_len      = 10,
 +              .sync           = 0,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} } };
 +size_t display_count = ARRAY_SIZE(displays);
 +
 +static void setup_display(void)
 +{
 +      struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +      struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 +      int reg;
 +
 +      /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
 +      imx_iomux_v3_setup_multiple_pads(di0_pads, ARRAY_SIZE(di0_pads));
 +
 +      enable_ipu_clock();
 +      imx_setup_hdmi();
 +
 +      /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
 +      reg = readl(&mxc_ccm->CCGR3);
 +      reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
 +      writel(reg, &mxc_ccm->CCGR3);
 +
 +      /* set LDB0, LDB1 clk select to 011/011 */
 +      reg = readl(&mxc_ccm->cs2cdr);
 +      reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
 +               | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
 +      reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 +            | (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
 +      writel(reg, &mxc_ccm->cs2cdr);
 +
 +      reg = readl(&mxc_ccm->cscmr2);
 +      reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
 +      writel(reg, &mxc_ccm->cscmr2);
 +
 +      reg = readl(&mxc_ccm->chsccdr);
 +      reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 +              << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
 +      reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 +              << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
 +      writel(reg, &mxc_ccm->chsccdr);
 +
 +      reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
 +           | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
 +           | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
 +           | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
 +           | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
 +           | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
 +           | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
 +           | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
 +           | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
 +      writel(reg, &iomux->gpr[2]);
 +
 +      reg = readl(&iomux->gpr[3]);
 +      reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
 +                      | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
 +          | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
 +             << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
 +      writel(reg, &iomux->gpr[3]);
 +}
 +#endif /* CONFIG_VIDEO_IPUV3 */
 +
 +/*
 + * Do not overwrite the console
 + * Use always serial for U-Boot console
 + */
 +int overwrite_console(void)
 +{
 +      return 1;
 +}
 +
 +int board_eth_init(bd_t *bis)
 +{
        setup_iomux_enet();
 +      setup_pcie();
 +
 +      return cpu_eth_init(bis);
 +}
 +
 +#ifdef CONFIG_USB_EHCI_MX6
 +#define USB_OTHERREGS_OFFSET  0x800
 +#define UCTRL_PWR_POL         (1 << 9)
  
 -      ret = cpu_eth_init(bis);
 -      if (ret)
 -              printf("FEC MXC: %s:failed\n", __func__);
 +static iomux_v3_cfg_t const usb_otg_pads[] = {
-       MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_EIM_D22__USB_OTG_PWR,
++      MX6_PAD_ENET_RX_ER__USB_OTG_ID,
 +};
 +
 +static iomux_v3_cfg_t const usb_hc1_pads[] = {
-       MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
++      MX6_PAD_ENET_TXD1__GPIO1_IO29,
 +};
 +
 +static void setup_usb(void)
 +{
 +      imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
 +                                       ARRAY_SIZE(usb_otg_pads));
 +
 +      /*
 +       * set daisy chain for otg_pin_id on 6q.
 +       * for 6dl, this bit is reserved
 +       */
 +      imx_iomux_set_gpr_register(1, 13, 1, 0);
 +
 +      imx_iomux_v3_setup_multiple_pads(usb_hc1_pads,
 +                                       ARRAY_SIZE(usb_hc1_pads));
 +}
 +
 +int board_ehci_hcd_init(int port)
 +{
 +      u32 *usbnc_usb_ctrl;
 +
 +      if (port > 1)
 +              return -EINVAL;
 +
 +      usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
 +                               port * 4);
 +
 +      setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
 +
 +      return 0;
 +}
 +
 +int board_ehci_power(int port, int on)
 +{
 +      switch (port) {
 +      case 0:
 +              break;
 +      case 1:
 +              if (on)
 +                      gpio_direction_output(IMX_GPIO_NR(1, 29), 1);
 +              else
 +                      gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
 +              break;
 +      default:
 +              printf("MXC USB port %d not yet supported\n", port);
 +              return -EINVAL;
 +      }
  
        return 0;
  }
 +#endif
  
  int board_early_init_f(void)
  {
        setup_iomux_uart();
 +#if defined(CONFIG_VIDEO_IPUV3)
 +      setup_display();
 +#endif
  
        return 0;
  }
@@@ -616,49 -253,9 +616,49 @@@ int board_init(void
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  
 +#ifdef CONFIG_MXC_SPI
 +      setup_spi();
 +#endif
 +      setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
 +
 +#ifdef CONFIG_USB_EHCI_MX6
 +      setup_usb();
 +#endif
 +
        return 0;
  }
  
 +int power_init_board(void)
 +{
 +      struct pmic *p;
 +      unsigned int reg;
 +
 +      p = pfuze_common_init(I2C_PMIC);
 +      if (!p)
 +              return -ENODEV;
 +
 +      /* Increase VGEN3 from 2.5 to 2.8V */
 +      pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
 +      reg &= ~LDO_VOL_MASK;
 +      reg |= LDOB_2_80V;
 +      pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
 +
 +      /* Increase VGEN5 from 2.8 to 3V */
 +      pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
 +      reg &= ~LDO_VOL_MASK;
 +      reg |= LDOB_3_00V;
 +      pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_MXC_SPI
 +int board_spi_cs_gpio(unsigned bus, unsigned cs)
 +{
 +      return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
 +}
 +#endif
 +
  #ifdef CONFIG_CMD_BMODE
  static const struct boot_mode board_boot_modes[] = {
        /* 4 bit bus width */
@@@ -675,6 -272,7 +675,6 @@@ int board_late_init(void
  #ifdef CONFIG_CMD_BMODE
        add_board_boot_modes(board_boot_modes);
  #endif
 -
        return 0;
  }
  
@@@ -683,169 -281,3 +683,169 @@@ int checkboard(void
        puts("Board: MX6-SabreSD\n");
        return 0;
  }
 +
 +#ifdef CONFIG_SPL_BUILD
 +#include <spl.h>
 +#include <libfdt.h>
 +
 +const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
 +      .dram_sdclk_0 =  0x00020030,
 +      .dram_sdclk_1 =  0x00020030,
 +      .dram_cas =  0x00020030,
 +      .dram_ras =  0x00020030,
 +      .dram_reset =  0x00020030,
 +      .dram_sdcke0 =  0x00003000,
 +      .dram_sdcke1 =  0x00003000,
 +      .dram_sdba2 =  0x00000000,
 +      .dram_sdodt0 =  0x00003030,
 +      .dram_sdodt1 =  0x00003030,
 +      .dram_sdqs0 =  0x00000030,
 +      .dram_sdqs1 =  0x00000030,
 +      .dram_sdqs2 =  0x00000030,
 +      .dram_sdqs3 =  0x00000030,
 +      .dram_sdqs4 =  0x00000030,
 +      .dram_sdqs5 =  0x00000030,
 +      .dram_sdqs6 =  0x00000030,
 +      .dram_sdqs7 =  0x00000030,
 +      .dram_dqm0 =  0x00020030,
 +      .dram_dqm1 =  0x00020030,
 +      .dram_dqm2 =  0x00020030,
 +      .dram_dqm3 =  0x00020030,
 +      .dram_dqm4 =  0x00020030,
 +      .dram_dqm5 =  0x00020030,
 +      .dram_dqm6 =  0x00020030,
 +      .dram_dqm7 =  0x00020030,
 +};
 +
 +const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
 +      .grp_ddr_type =  0x000C0000,
 +      .grp_ddrmode_ctl =  0x00020000,
 +      .grp_ddrpke =  0x00000000,
 +      .grp_addds =  0x00000030,
 +      .grp_ctlds =  0x00000030,
 +      .grp_ddrmode =  0x00020000,
 +      .grp_b0ds =  0x00000030,
 +      .grp_b1ds =  0x00000030,
 +      .grp_b2ds =  0x00000030,
 +      .grp_b3ds =  0x00000030,
 +      .grp_b4ds =  0x00000030,
 +      .grp_b5ds =  0x00000030,
 +      .grp_b6ds =  0x00000030,
 +      .grp_b7ds =  0x00000030,
 +};
 +
 +const struct mx6_mmdc_calibration mx6_mmcd_calib = {
 +      .p0_mpwldectrl0 =  0x001F001F,
 +      .p0_mpwldectrl1 =  0x001F001F,
 +      .p1_mpwldectrl0 =  0x00440044,
 +      .p1_mpwldectrl1 =  0x00440044,
 +      .p0_mpdgctrl0 =  0x434B0350,
 +      .p0_mpdgctrl1 =  0x034C0359,
 +      .p1_mpdgctrl0 =  0x434B0350,
 +      .p1_mpdgctrl1 =  0x03650348,
 +      .p0_mprddlctl =  0x4436383B,
 +      .p1_mprddlctl =  0x39393341,
 +      .p0_mpwrdlctl =  0x35373933,
 +      .p1_mpwrdlctl =  0x48254A36,
 +};
 +
 +static struct mx6_ddr3_cfg mem_ddr = {
 +      .mem_speed = 1600,
 +      .density = 4,
 +      .width = 64,
 +      .banks = 8,
 +      .rowaddr = 14,
 +      .coladdr = 10,
 +      .pagesz = 2,
 +      .trcd = 1375,
 +      .trcmin = 4875,
 +      .trasmin = 3500,
 +};
 +
 +static void ccgr_init(void)
 +{
 +      struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 +
 +      writel(0x00C03F3F, &ccm->CCGR0);
 +      writel(0x0030FC03, &ccm->CCGR1);
 +      writel(0x0FFFC000, &ccm->CCGR2);
 +      writel(0x3FF00000, &ccm->CCGR3);
 +      writel(0x00FFF300, &ccm->CCGR4);
 +      writel(0x0F0000C3, &ccm->CCGR5);
 +      writel(0x000003FF, &ccm->CCGR6);
 +}
 +
 +static void gpr_init(void)
 +{
 +      struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 +
 +      /* enable AXI cache for VDOA/VPU/IPU */
 +      writel(0xF00000CF, &iomux->gpr[4]);
 +      /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
 +      writel(0x007F007F, &iomux->gpr[6]);
 +      writel(0x007F007F, &iomux->gpr[7]);
 +}
 +
 +/*
 + * This section requires the differentiation between iMX6 Sabre boards, but
 + * for now, it will configure only for the mx6q variant.
 + */
 +static void spl_dram_init(void)
 +{
 +      struct mx6_ddr_sysinfo sysinfo = {
 +              /* width of data bus:0=16,1=32,2=64 */
 +              .dsize = mem_ddr.width/32,
 +              /* config for full 4GB range so that get_mem_size() works */
 +              .cs_density = 32, /* 32Gb per CS */
 +              /* single chip select */
 +              .ncs = 1,
 +              .cs1_mirror = 0,
 +              .rtt_wr = 1 /*DDR3_RTT_60_OHM*/,        /* RTT_Wr = RZQ/4 */
 +#ifdef RTT_NOM_120OHM
 +              .rtt_nom = 2 /*DDR3_RTT_120_OHM*/,      /* RTT_Nom = RZQ/2 */
 +#else
 +              .rtt_nom = 1 /*DDR3_RTT_60_OHM*/,       /* RTT_Nom = RZQ/4 */
 +#endif
 +              .walat = 1,     /* Write additional latency */
 +              .ralat = 5,     /* Read additional latency */
 +              .mif3_mode = 3, /* Command prediction working mode */
 +              .bi_on = 1,     /* Bank interleaving enabled */
 +              .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
 +              .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
 +      };
 +
 +      mx6dq_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
 +      mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
 +}
 +
 +void board_init_f(ulong dummy)
 +{
 +      /* setup AIPS and disable watchdog */
 +      arch_cpu_init();
 +
 +      ccgr_init();
 +      gpr_init();
 +
 +      /* iomux and setup of i2c */
 +      board_early_init_f();
 +
 +      /* setup GP timer */
 +      timer_init();
 +
 +      /* UART clocks enabled and gd valid - init serial console */
 +      preloader_console_init();
 +
 +      /* DDR initialization */
 +      spl_dram_init();
 +
 +      /* Clear the BSS. */
 +      memset(__bss_start, 0, __bss_end - __bss_start);
 +
 +      /* load/boot image from boot device */
 +      board_init_r(NULL, 0);
 +}
 +
 +void reset_cpu(ulong addr)
 +{
 +}
 +#endif
index 0000000000000000000000000000000000000000,8e22489c3dd40abd87c07fbede8548fda55c9dd9..05c1d343a03e49d17812cd623e7efbaca1e1bd0f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,50 +1,13 @@@
 -# (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# See file CREDITS for list of people who contributed to this
 -# project.
 -#
 -# 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.
++# (C) Copyright 2012-2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -include $(TOPDIR)/config.mk
 -
 -ifneq ($(OBJTREE),$(SRCTREE))
 -$(shell mkdir -p $(obj)board/$(VENDOR)/common)
 -endif
 -
 -LIB   = $(obj)lib$(VENDOR).o
 -
++# SPDX-License-Identifier:    GPL-2.0+
+ #
 -      COBJS-$(CONFIG_OF_BOARD_SETUP)  += fdt.o
 -      COBJS-$(CONFIG_SPLASH_SCREEN)   += splashimage.o
+ ifeq ($(CONFIG_SPL_BUILD),)
 -COBJS-$(CONFIG_CMD_NAND)              += nand.o
 -COBJS-$(CONFIG_ENV_IS_IN_MMC)         += mmc.o
 -COBJS-y                               += env.o
 -COBJS   := $(COBJS-y)
 -SOBJS := 
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -SOBJS := $(addprefix $(obj),$(SOBJS))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -all:  $(LIB)
 -
 -#########################################################################
 -
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
++      obj-$(CONFIG_OF_LIBFDT)         += fdt.o
++      obj-$(CONFIG_SPLASH_SCREEN)     += splashimage.o
+ endif
++obj-$(CONFIG_CMD_NAND)                        += nand.o
++obj-$(CONFIG_ENV_IS_IN_MMC)           += mmc.o
++obj-y                                         += env.o
diff --combined board/karo/common/karo.h
index 0000000000000000000000000000000000000000,d078828d116f8ec881c1472979b43cfc136076c5..aff9f370915801b1c6f682ead0a7af6c59fdc544
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,157 +1,159 @@@
+ /*
+  * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+ */
+ struct fb_videomode;
+ #ifdef CONFIG_SYS_LVDS_IF
+ #define is_lvds()                     1
+ #else
+ #define is_lvds()                     0
+ #endif
+ void env_cleanup(void);
+ #ifdef CONFIG_OF_LIBFDT
+ void karo_fdt_remove_node(void *blob, const char *node);
+ void karo_fdt_move_fdt(void);
+ void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
+                       size_t num_panels);
+ void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
+                       const char *phy_supply);
+ void karo_fdt_fixup_flexcan(void *blob, int xcvr_present);
+ void karo_fdt_del_prop(void *blob, const char *compat, u32 offs,
+               const char *prop);
+ void karo_fdt_enable_node(void *blob, const char *node, int enable);
+ int karo_fdt_get_fb_mode(void *blob, const char *name,
+               struct fb_videomode *fb_mode);
+ int karo_fdt_update_fb_mode(void *blob, const char *name);
+ int karo_fdt_create_fb_mode(void *blob, const char *name,
+                       struct fb_videomode *mode);
+ int karo_fdt_get_backlight_polarity(const void *blob);
+ #else
+ static inline void karo_fdt_remove_node(void *blob, const char *node)
+ {
+ }
+ static inline void karo_fdt_move_fdt(void)
+ {
+ }
+ static inline void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
+                                       size_t num_panels)
+ {
+ }
+ static inline void karo_fdt_fixup_usb_otg(void *blob, const char *node,
+                                       const char *phy,
+                                       const char *phy_supply)
+ {
+ }
+ static inline void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+ {
+ }
+ static inline void karo_fdt_del_prop(void *blob, const char *compat,
+                               u32 offs, const char *prop)
+ {
+ }
+ static inline void karo_fdt_enable_node(void *blob, const char *node,
+                                       int enable)
+ {
+ }
+ static inline int karo_fdt_get_fb_mode(void *blob, const char *name,
+                               struct fb_videomode *fb_mode)
+ {
+       return 0;
+ }
+ static inline int karo_fdt_update_fb_mode(void *blob, const char *name)
+ {
+       return 0;
+ }
+ static inline int karo_fdt_create_fb_mode(void *blob,
+                                       const char *name,
+                                       struct fb_videomode *mode)
+ {
+       return 0;
+ }
+ static inline int karo_fdt_get_backlight_polarity(const void *blob)
+ {
+       return getenv_yesno("backlight_polarity");
+ }
+ #endif
+ #if defined(CONFIG_SYS_LVDS_IF) && defined(CONFIG_OF_LIBFDT)
+ int karo_fdt_get_lcd_bus_width(const void *blob, int default_width);
+ int karo_fdt_get_lvds_mapping(const void *blob, int default_mapping);
+ u8 karo_fdt_get_lvds_channels(const void *blob);
+ #else
+ static inline int karo_fdt_get_lcd_bus_width(const void *blob, int default_width)
+ {
+       return default_width;
+ }
+ static inline int karo_fdt_get_lvds_mapping(const void *blob, int default_mapping)
+ {
+       return default_mapping;
+ }
+ static inline u8 karo_fdt_get_lvds_channels(const void *blob)
+ {
+       return 0;
+ }
+ #endif
+ static inline const char *karo_get_vmode(const char *video_mode)
+ {
+       const char *vmode = NULL;
+       if (video_mode == NULL || strlen(video_mode) == 0)
+               return NULL;
+       vmode = strchr(video_mode, ':');
+       return vmode ? vmode + 1 : video_mode;
+ }
+ #ifdef CONFIG_SPLASH_SCREEN
+ int karo_load_splashimage(int mode);
+ #else
+ static inline int karo_load_splashimage(int mode)
+ {
+       return 0;
+ }
+ #endif
+ #ifdef CONFIG_CMD_NAND
+ int karo_load_nand_part(const char *part, void *addr, size_t len);
+ #else
+ static inline int karo_load_nand_part(const char *part, void *addr, size_t len)
+ {
+       return -EOPNOTSUPP;
+ }
+ #endif
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ int karo_load_mmc_part(const char *part, void *addr, size_t len);
+ #else
+ static inline int karo_load_mmc_part(const char *part, void *addr, size_t len)
+ {
+       return -EOPNOTSUPP;
+ }
+ #endif
+ static inline int karo_load_part(const char *part, void *addr, size_t len)
+ {
+       int ret;
+       ret = karo_load_nand_part(part, addr, len);
+       if (ret == -EOPNOTSUPP)
+               return karo_load_mmc_part(part, addr, len);
+       return ret;
+ }
++
++#define DIV_ROUND(n, d)               (((n) + (d) / 2) / (d))
diff --combined board/karo/common/mmc.c
index 0000000000000000000000000000000000000000,c6a7a3d5a101296319c72f9bc761d7fcfe47a108..b452a0b1e8123fcd02a303c5a16740cdcad48f62
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,180 +1,186 @@@
 -              int len_read;
 -
 -              printf("Reading file %s from mmc partition %d\n", part, 0);
 -              len_read = fs_read(part, (ulong)addr, 0, len);
+ /*
+  * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <mmc.h>
+ #include <mxcfb.h>
+ #include <fs.h>
+ #include <fat.h>
+ #include <malloc.h>
+ #include <linux/list.h>
+ #include <linux/fb.h>
+ #include <jffs2/load_kernel.h>
+ #include "karo.h"
+ DECLARE_GLOBAL_DATA_PTR;
+ #define MAX_SEARCH_PARTITIONS 16
+ static int find_partitions(const char *ifname, int devno, int fstype,
+                       block_dev_desc_t **dev_desc, disk_partition_t *info)
+ {
+       int ret = -1;
+       char *dup_str = NULL;
+       int p;
+       int part;
+       block_dev_desc_t *dd;
+       dd = get_dev(ifname, devno);
+       if (!dd || dd->type == DEV_TYPE_UNKNOWN) {
+               printf("** Bad device %s %d **\n", ifname, devno);
+               return -1;
+       }
+       init_part(dd);
+       /*
+        * No partition table on device,
+        * or user requested partition 0 (entire device).
+        */
+       if (dd->part_type == PART_TYPE_UNKNOWN) {
+               printf("** No partition table on device %s %d **\n",
+                       ifname, devno);
+               goto cleanup;
+       }
+       part = 0;
+       for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
+               ret = get_partition_info(dd, p, info);
+               if (ret)
+                       continue;
+               if (fat_register_device(dd, p) == 0) {
+                       part = p;
+                       dd->log2blksz = LOG2(dd->blksz);
+                       break;
+               }
+       }
+       if (!part) {
+               printf("** No valid partition on device %s %d **\n",
+                       ifname, devno);
+               ret = -1;
+               goto cleanup;
+       }
+       ret = part;
+       *dev_desc = dd;
+ cleanup:
+       free(dup_str);
+       return ret;
+ }
+ static int karo_mmc_find_part(struct mmc *mmc, const char *part, int devno,
+                       disk_partition_t *part_info)
+ {
+       int ret;
+       block_dev_desc_t *mmc_dev;
+ #if defined(CONFIG_SYS_DTB_OFFSET) && defined(CONFIG_SYS_MMC_ENV_PART)
+       if (strcmp(part, "dtb") == 0) {
+               const int partnum = CONFIG_SYS_MMC_ENV_PART;
+               part_info->blksz = mmc->read_bl_len;
+               part_info->start = CONFIG_SYS_DTB_OFFSET / part_info->blksz;
+               part_info->size = CONFIG_SYS_DTB_PART_SIZE / part_info->blksz;
+               printf("Using virtual partition %s(%d) ["LBAF".."LBAF"]\n",
+                       part, partnum, part_info->start,
+                       part_info->start + part_info->size - 1);
+               return partnum;
+       }
+ #endif
+       ret = find_partitions("mmc", devno, FS_TYPE_FAT, &mmc_dev, part_info);
+       if (ret < 0) {
+               printf("No (e)MMC partition found: %d\n", ret);
+               return ret;
+       }
+       return 0;
+ }
+ int karo_load_mmc_part(const char *part, void *addr, size_t len)
+ {
+       int ret;
+       struct mmc *mmc;
+       disk_partition_t part_info;
+       int devno = CONFIG_SYS_MMC_ENV_DEV;
+       lbaint_t blk_cnt;
+       int partnum;
+       mmc = find_mmc_device(devno);
+       if (!mmc) {
+               printf("Failed to find mmc%u\n", devno);
+               return -ENODEV;
+       }
+       if (mmc_init(mmc)) {
+               printf("Failed to init MMC device %d\n", devno);
+               return -EIO;
+       }
+       blk_cnt = DIV_ROUND_UP(len, mmc->read_bl_len);
+       partnum = karo_mmc_find_part(mmc, part, devno, &part_info);
+       if (partnum > 0) {
+               if (part_info.start + blk_cnt < part_info.start) {
+                       printf("%s: given length 0x%08x exceeds size of partition\n",
+                               __func__, len);
+                       return -EINVAL;
+               }
+               if (part_info.start + blk_cnt > mmc->block_dev.lba)
+                       blk_cnt = mmc->block_dev.lba - part_info.start;
+               mmc_switch_part(devno, partnum);
+               memset(addr, 0xee, len);
+               debug("Reading 0x"LBAF" blks from MMC partition %d offset 0x"LBAF" to %p\n",
+                       blk_cnt, partnum, part_info.start, addr);
+               ret = mmc->block_dev.block_read(devno, part_info.start, blk_cnt, addr);
+               if (ret == 0) {
+                       printf("Failed to read MMC partition %s\n", part);
+                       ret = -EIO;
+                       goto out;
+               }
+               debug("Read %u (%u) byte from partition '%s' @ offset 0x"LBAF"\n",
+                       ret * mmc->read_bl_len, len, part, part_info.start);
+       } else if (partnum == 0) {
 -                      printf("Read only %u of %u bytes\n", len_read, len);
++              loff_t len_read;
++
++              debug("Reading file %s from mmc partition %d\n", part,
++                      partnum);
++              ret = fs_read(part, (ulong)addr, 0, len, &len_read);
++              if (ret < 0) {
++                      printf("Failed to read %u byte from mmc partition %d\n",
++                              len, partnum);
++                      goto out;
++              }
+               if (len_read < len) {
++                      printf("Read only %llu of %u bytes\n", (u64)len_read, len);
+               }
+       } else {
+               ret = partnum;
+               goto out;
+       }
+       ret = 0;
+ out:
+       if (partnum > 0)
+               mmc_switch_part(devno, 0);
+       return ret < 0 ? ret : 0;
+ }
diff --combined board/karo/common/nand.c
index 0000000000000000000000000000000000000000,c982901c7f265aae46c31ba33dcea94eab9c7305..6d303f01d83e111208ef8e0ffe63452a961e4622
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,157 +1,157 @@@
 -      debug("Found partition '%s': offset=%08x size=%08x\n",
 -              part, part_info->offset, part_info->size);
+ /*
+  * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+ */
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <nand.h>
+ #include <mxcfb.h>
+ #include <linux/list.h>
+ #include <linux/fb.h>
+ #include <jffs2/load_kernel.h>
+ #include <malloc.h>
+ #include "karo.h"
+ #ifdef CONFIG_MAX_DTB_SIZE
+ #define MAX_DTB_SIZE  CONFIG_MAX_DTB_SIZE
+ #else
+ #define MAX_DTB_SIZE  SZ_64K
+ #endif
+ DECLARE_GLOBAL_DATA_PTR;
+ int karo_load_nand_part(const char *part, void *addr, size_t len)
+ {
+       int ret;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+       debug("Initializing mtd_parts\n");
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+       debug("Trying to find NAND partition '%s'\n", part);
+       ret = find_dev_and_part(part, &dev, &part_num, &part_info);
+       if (ret) {
+               printf("Failed to find flash partition '%s': %d\n",
+                       part, ret);
+               return ret;
+       }
 -      debug("Read %u byte from partition '%s' @ offset %08x\n",
 -              len, part, part_info->offset);
++      debug("Found partition '%s': offset=%08llx size=%08llx\n",
++              part, (u64)part_info->offset, (u64)part_info->size);
+       if (part_info->size < len)
+               len = part_info->size;
+       debug("Reading NAND partition '%s' to %p\n", part, addr);
+       ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len,
+                               NULL, part_info->size, addr);
+       if (ret) {
+               printf("Failed to load partition '%s' to %p\n", part, addr);
+               return ret;
+       }
++      debug("Read %u byte from partition '%s' @ offset %08llx\n",
++              len, part, (u64)part_info->offset);
+       return 0;
+ }
+ #if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_MTDPARTS)
+ static int erase_flash(loff_t offs, size_t len)
+ {
+       nand_erase_options_t nand_erase_options;
+       memset(&nand_erase_options, 0, sizeof(nand_erase_options));
+       nand_erase_options.length = len;
+       nand_erase_options.offset = offs;
+       return nand_erase_opts(&nand_info[0], &nand_erase_options);
+ }
+ int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int ret;
+       size_t fbsize = calc_fbsize();
+       const char *part = "logo";
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+       u_char *addr = (u_char *)gd->fb_base;
+       if (argc > 2)
+               return CMD_RET_USAGE;
+       if (argc == 2)
+               part = argv[1];
+       if (!addr) {
+               printf("fb address unknown\n");
+               return CMD_RET_FAILURE;
+       }
+       debug("Initializing mtd_parts\n");
+       ret = mtdparts_init();
+       if (ret)
+               return CMD_RET_FAILURE;
+       debug("Trying to find NAND partition '%s'\n", part);
+       ret = find_dev_and_part(part, &dev, &part_num,
+                               &part_info);
+       if (ret) {
+               printf("Failed to find flash partition '%s': %d\n",
+                       part, ret);
+               return CMD_RET_FAILURE;
+       }
+       debug("Found partition '%s': offset=%08x size=%08x\n",
+               part, part_info->offset, part_info->size);
+       if (part_info->size < fbsize) {
+               printf("Error: partition '%s' smaller than frame buffer size: %u\n",
+                       part, fbsize);
+               return CMD_RET_FAILURE;
+       }
+       debug("Writing framebuffer %p to NAND partition '%s'\n",
+               addr, part);
+       ret = erase_flash(part_info->offset, fbsize);
+       if (ret) {
+               printf("Failed to erase partition '%s'\n", part);
+               return CMD_RET_FAILURE;
+       }
+       ret = nand_write_skip_bad(&nand_info[0], part_info->offset,
+                               &fbsize, NULL, part_info->size,
+                               addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to write partition '%s'\n", part);
+               return CMD_RET_FAILURE;
+       }
+       debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n",
+               fbsize, addr, part, part_info->offset);
+       return CMD_RET_SUCCESS;
+ }
+ U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash",
+       "[partition name]\n"
+       "       default partition name: 'logo'\n");
+ #endif
diff --combined board/karo/tx28/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..896ee62d1bb2eaadc3e0d236de70890c50ec1d9f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,127 @@@
++if TARGET_TX28_40X1
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x1"
++
++endif
++
++if TARGET_TX28_40X1_NOENV
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x1_noenv"
++
++endif
++
++if TARGET_TX28_40X2
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x2"
++
++endif
++
++if TARGET_TX28_40X2_NOENV
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x2_noenv"
++
++endif
++
++if TARGET_TX28_40X3
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x3"
++
++endif
++
++if TARGET_TX28_40X3_NOENV
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-40x3_noenv"
++
++endif
++
++if TARGET_TX28_41X0
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-41x0"
++
++endif
++
++if TARGET_TX28_41X0_NOENV
++
++config SYS_BOARD
++      default "tx28"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mxs"
++
++config SYS_CONFIG_NAME
++      default "tx28-41x0_noenv"
++
++endif
diff --combined board/karo/tx28/Makefile
index 0000000000000000000000000000000000000000,e7931405f3ac1d3d6daccebc8998befd10629f5b..698298c829f9ec8745fae3c3864dba66eedaf2f3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,53 +1,11 @@@
 -# (C) Copyright 2009 DENX Software Engineering
 -# Author: John Rigby <jcrigby@gmail.com>
+ #
 -# See file CREDITS for list of people who contributed to this
 -# project.
++# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# This program is free software; you can redistribute it and/or
 -# modify it under the terms of the GNU General Public License as
 -# published by the Free Software Foundation; either version 2 of
 -# the License, or (at your option) any later version.
 -#
 -# 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 $(TOPDIR)/config.mk
++# SPDX-License-Identifier:    GPL-2.0+
+ #
 -LIB   = $(obj)lib$(BOARD).o
 -
 -COBJS := tx28.o
 -ifeq ($(CONFIG_SPL_BUILD),y)
 -      COBJS += spl_boot.o
 -else
 -ifeq ($(CONFIG_CMD_ROMUPDATE),y)
 -      COBJS += flash.o
 -endif
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -SOBJS := $(addprefix $(obj),$(SOBJS))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -$(obj)u-boot.db: u-boot.db.in
 -      sed "s:@@BUILD_DIR@@:${BUILD_DIR:-.}/:" $< > $@
 -
 -#########################################################################
 -
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
++obj-y                         += tx28.o
++obj-$(CONFIG_SPL_BUILD)               += spl_boot.o
++ifneq ($(CONFIG_SPL_BUILD),y)
++      obj-$(CONFIG_CMD_ROMUPDATE) += flash.o
+ endif
diff --combined board/karo/tx28/flash.c
index 0000000000000000000000000000000000000000,792df78e3eb61769ed9d668e9aa992e9dfee433e..9234e721b5b74381eaecf3e5e1d3512343dea1c9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,663 +1,663 @@@
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2011-2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <malloc.h>
+ #include <nand.h>
+ #include <errno.h>
+ #include <linux/err.h>
+ #include <jffs2/load_kernel.h>
+ #include <asm/io.h>
++#include <linux/sizes.h>
+ #include <asm/arch/regs-base.h>
+ #include <asm/imx-common/regs-gpmi.h>
+ #include <asm/imx-common/regs-bch.h>
+ struct mx28_nand_timing {
+       u8 data_setup;
+       u8 data_hold;
+       u8 address_setup;
+       u8 dsample_time;
+       u8 nand_timing_state;
+       u8 tREA;
+       u8 tRLOH;
+       u8 tRHOH;
+ };
+ struct mx28_fcb {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       struct mx28_nand_timing timing;
+       u32 page_data_size;
+       u32 total_page_size;
+       u32 sectors_per_block;
+       u32 number_of_nands;    /* not used by ROM code */
+       u32 total_internal_die; /* not used by ROM code */
+       u32 cell_type;          /* not used by ROM code */
+       u32 ecc_blockn_type;
+       u32 ecc_block0_size;
+       u32 ecc_blockn_size;
+       u32 ecc_block0_type;
+       u32 metadata_size;
+       u32 ecc_blocks_per_page;
+       u32 rsrvd[6];            /* not used by ROM code */
+       u32 bch_mode;
+       u32 boot_patch;
+       u32 patch_sectors;
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 fw1_sectors;
+       u32 fw2_sectors;
+       u32 dbbt_search_area;
+       u32 bb_mark_byte;
+       u32 bb_mark_startbit;
+       u32 bb_mark_phys_offset;
+ };
+ #define BF_VAL(v, bf)         (((v) & bf##_MASK) >> bf##_OFFSET)
+ static nand_info_t *mtd = &nand_info[0];
+ extern void *_start;
+ #define BIT(v,n)      (((v) >> (n)) & 0x1)
+ static u8 calculate_parity_13_8(u8 d)
+ {
+       u8 p = 0;
+       p |= (BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 3) ^ BIT(d, 2))             << 0;
+       p |= (BIT(d, 7) ^ BIT(d, 5) ^ BIT(d, 4) ^ BIT(d, 2) ^ BIT(d, 1)) << 1;
+       p |= (BIT(d, 7) ^ BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 1) ^ BIT(d, 0)) << 2;
+       p |= (BIT(d, 7) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 0))             << 3;
+       p |= (BIT(d, 6) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 2) ^ BIT(d, 1) ^ BIT(d, 0)) << 4;
+       return p;
+ }
+ static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+ {
+       int i;
+       u8 *src = _src;
+       u8 *ecc = _ecc;
+       for (i = 0; i < size; i++)
+               ecc[i] = calculate_parity_13_8(src[i]);
+ }
+ static u32 calc_chksum(void *buf, size_t size)
+ {
+       u32 chksum = 0;
+       u8 *bp = buf;
+       size_t i;
+       for (i = 0; i < size; i++) {
+               chksum += bp[i];
+       }
+       return ~chksum;
+ }
+ /*
+   Physical organisation of data in NAND flash:
+   metadata
+   payload chunk 0 (may be empty)
+   ecc for metadata + payload chunk 0
+   payload chunk 1
+   ecc for payload chunk 1
+ ...
+   payload chunk n
+   ecc for payload chunk n
+  */
+ static int calc_bb_offset(nand_info_t *mtd, struct mx28_fcb *fcb)
+ {
+       int bb_mark_offset;
+       int chunk_data_size = fcb->ecc_blockn_size * 8;
+       int chunk_ecc_size = (fcb->ecc_blockn_type << 1) * 13;
+       int chunk_total_size = chunk_data_size + chunk_ecc_size;
+       int bb_mark_chunk, bb_mark_chunk_offs;
+       bb_mark_offset = (mtd->writesize - fcb->metadata_size) * 8;
+       if (fcb->ecc_block0_size == 0)
+               bb_mark_offset -= (fcb->ecc_block0_type << 1) * 13;
+       bb_mark_chunk = bb_mark_offset / chunk_total_size;
+       bb_mark_chunk_offs = bb_mark_offset - (bb_mark_chunk * chunk_total_size);
+       if (bb_mark_chunk_offs > chunk_data_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       bb_mark_offset -= bb_mark_chunk * chunk_ecc_size;
+       return bb_mark_offset;
+ }
+ /*
+  * return number of blocks to skip for a contiguous partition
+  * of given # blocks
+  */
+ static int find_contig_space(int block, int num_blocks, int max_blocks)
+ {
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+ }
+ #define pr_fcb_val(p, n)      debug("%s=%08x(%d)\n", #n, (p)->n, (p)->n)
+ static struct mx28_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+ {
+       struct gpmi_regs *gpmi_base = (void *)GPMI_BASE_ADDRESS;
+       struct bch_regs *bch_base = (void *)BCH_BASE_ADDRESS;
+       u32 fl0, fl1;
+       u32 t0;
+       int metadata_size;
+       int bb_mark_bit_offs;
+       struct mx28_fcb *fcb;
+       int fcb_offs;
+       if (gpmi_base == NULL || bch_base == NULL) {
+               return ERR_PTR(-ENOMEM);
+       }
+       fl0 = readl(&bch_base->hw_bch_flash0layout0);
+       fl1 = readl(&bch_base->hw_bch_flash0layout1);
+       t0 = readl(&gpmi_base->hw_gpmi_timing0);
+       metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb = buf + ALIGN(metadata_size, 4);
+       fcb_offs = (void *)fcb - buf;
+       memset(buf, 0xff, fcb_offs);
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - fcb_offs - sizeof(*fcb));
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = cpu_to_be32(1);
+       /* ROM code assumes GPMI clock of 25 MHz */
+       fcb->timing.data_setup = BF_VAL(t0, GPMI_TIMING0_DATA_SETUP) * 40;
+       fcb->timing.data_hold = BF_VAL(t0, GPMI_TIMING0_DATA_HOLD) * 40;
+       fcb->timing.address_setup = BF_VAL(t0, GPMI_TIMING0_ADDRESS_SETUP) * 40;
+       fcb->page_data_size = mtd->writesize;
+       fcb->total_page_size = mtd->writesize + mtd->oobsize;
+       fcb->sectors_per_block = mtd->erasesize / mtd->writesize;
+       fcb->ecc_block0_type = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
+       fcb->ecc_block0_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE);
+       fcb->ecc_blockn_type = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
+       fcb->ecc_blockn_size = BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE);
+       pr_fcb_val(fcb, ecc_block0_type);
+       pr_fcb_val(fcb, ecc_blockn_type);
+       pr_fcb_val(fcb, ecc_block0_size);
+       pr_fcb_val(fcb, ecc_blockn_size);
+       fcb->metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb->ecc_blocks_per_page = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+       fcb->bch_mode = readl(&bch_base->hw_bch_mode);
+       fcb->fw1_start_page = fw1_start_block * fcb->sectors_per_block;
+       fcb->fw1_sectors = fw_num_blocks * fcb->sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+       pr_fcb_val(fcb, fw1_sectors);
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * fcb->sectors_per_block;
+               fcb->fw2_sectors = fcb->fw1_sectors;
+               pr_fcb_val(fcb, fw2_start_page);
+               pr_fcb_val(fcb, fw2_sectors);
+       }
+       fcb->dbbt_search_area = 1;
+       bb_mark_bit_offs = calc_bb_offset(mtd, fcb);
+       if (bb_mark_bit_offs < 0)
+               return ERR_PTR(bb_mark_bit_offs);
+       fcb->bb_mark_byte = bb_mark_bit_offs / 8;
+       fcb->bb_mark_startbit = bb_mark_bit_offs % 8;
+       fcb->bb_mark_phys_offset = mtd->writesize;
+       pr_fcb_val(fcb, bb_mark_byte);
+       pr_fcb_val(fcb, bb_mark_startbit);
+       pr_fcb_val(fcb, bb_mark_phys_offset);
+       fcb->checksum = calc_chksum(&fcb->fingerprint, 512 - 4);
+       return fcb;
+ }
+ static int find_fcb(void *ref, int page)
+ {
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+ out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+ }
+ static int write_fcb(void *buf, int block)
+ {
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+       ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+       if (ret) {
+               printf("Failed to erase FCB block %u\n", block);
+               return ret;
+       }
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       chip->select_chip(mtd, 0);
+       ret = chip->write_page(mtd, chip, buf, 1, page, 0, 1);
+       if (ret) {
+               printf("Failed to write FCB to block %u: %d\n", block, ret);
+       }
+       chip->select_chip(mtd, -1);
+       return ret;
+ }
+ #define chk_overlap(a,b)                              \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+ #define fail_if_overlap(a,b,m1,m2) do {                               \
+       if (chk_overlap(a, b)) {                                \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,     \
+                       m2, b##_start_block, b##_end_block);    \
+               return -EINVAL;                                 \
+       }                                                       \
+ } while (0)
+ static int tx28_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+ {
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = (start_block + skip) * mtd->erasesize;
+       erase_opts.offset = start_block * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       ret = nand_erase_opts(mtd, &erase_opts);
+       if (ret) {
+               printf("Failed to erase flash: %d\n", ret);
+               return ret;
+       }
+       printf("Programming flash @ %08llx..%08llx from %p\n",
+               (u64)start_block * mtd->erasesize,
+               (u64)start_block * mtd->erasesize + size - 1, addr);
+       actual = size;
+       ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                               prg_length, addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to program flash: %d\n", ret);
+               return ret;
+       }
+       if (actual < size) {
+               printf("Could only write %u of %u bytes\n", actual, size);
+               return -EIO;
+       }
+       return 0;
+ }
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #ifndef CONFIG_ENV_OFFSET_REDUND
+ #define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+ #else
+ #define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+ #endif
+ #endif
+ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx28_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+ #endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               printf("WARNING: Image size not specified; overwriting whole uboot partition\n");
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0) {
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       } else {
+               fw_num_blocks = part_info->size / mtd->erasesize -
+                       extra_blocks;
+               size = fw_num_blocks * mtd->erasesize;
+       }
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image\n",
+                       fw_num_blocks);
+               if (uboot_part) {
+ #ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+ #else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+ #endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       fw1_end_block = fw1_start_block + fw1_skip + fw_num_blocks - 1;
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image\n",
+                               fw_num_blocks);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       fw2_end_block = fw2_start_block + fw2_skip + fw_num_blocks - 1;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+ #endif
+       fail_if_overlap(fcb, fw1, "FCB", "FW1");
+       if (fw2_set) {
+               fail_if_overlap(fcb, fw2, "FCB", "FW2");
+ #ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+ #endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+       fcb = create_fcb(buf, fw1_start_block + fw1_skip,
+                       fw2_start_block + fw2_skip, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+       encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block + fw1_skip,
+               (u64)(fw1_start_block + fw1_skip) * mtd->erasesize);
+       ret = tx28_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+       if (fw2_start_block == 0) {
+               return ret;
+       }
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block + fw2_skip,
+               (u64)(fw2_start_block + fw2_skip) * mtd->erasesize);
+       ret = tx28_prog_uboot(addr, fw2_start_block, fw2_skip, fw_num_blocks,
+                       max_len2);
+       return ret;
+ }
+ U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\twrite bootloader image at block # (decimal)\n"
+       "\t-r\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\tspecify number of redundant blocks per boot loader image\n"
+       "\t\tonly valid if -f or -r specify a flash address rather than a partition name\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr}\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize}"
+       );
diff --combined board/karo/tx28/tx28.c
index 0000000000000000000000000000000000000000,e140e22d51bb0d5191acb54f08df3fd143fde63c..c578c0650ea3b5a0b1c972d5007b88fabbc906ed
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1015 +1,1018 @@@
 -      { TX28_USBH_VBUSEN_GPIO, GPIOF_OUTPUT_INIT_LOW, "USBH VBUSEN", },
 -      { TX28_USBH_OC_GPIO, GPIOF_INPUT, "USBH OC", },
 -      { TX28_USBOTG_VBUSEN_GPIO, GPIOF_OUTPUT_INIT_LOW, "USBOTG VBUSEN", },
 -      { TX28_USBOTG_OC_GPIO, GPIOF_INPUT, "USBOTG OC", },
 -      { TX28_USBOTG_ID_GPIO, GPIOF_INPUT, "USBOTG ID", },
+ /*
+  * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+  * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <lcd.h>
+ #include <netdev.h>
+ #include <mmc.h>
+ #include <mxcfb.h>
+ #include <linux/list.h>
+ #include <linux/fb.h>
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <asm/arch/iomux-mx28.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/sys_proto.h>
+ #include "../common/karo.h"
+ DECLARE_GLOBAL_DATA_PTR;
+ #define MXS_GPIO_NR(p, o)      (((p) << 5) | (o))
+ #define TX28_LCD_PWR_GPIO     MX28_PAD_LCD_ENABLE__GPIO_1_31
+ #define TX28_LCD_RST_GPIO     MX28_PAD_LCD_RESET__GPIO_3_30
+ #define TX28_LCD_BACKLIGHT_GPIO       MX28_PAD_PWM0__GPIO_3_16
+ #define TX28_USBH_VBUSEN_GPIO MX28_PAD_SPDIF__GPIO_3_27
+ #define TX28_USBH_OC_GPIO     MX28_PAD_JTAG_RTCK__GPIO_4_20
+ #define TX28_USBOTG_VBUSEN_GPIO       MX28_PAD_GPMI_CE2N__GPIO_0_18
+ #define TX28_USBOTG_OC_GPIO   MX28_PAD_GPMI_CE3N__GPIO_0_19
+ #define TX28_USBOTG_ID_GPIO   MX28_PAD_PWM2__GPIO_3_18
+ #define TX28_LED_GPIO         MX28_PAD_ENET0_RXD3__GPIO_4_10
+ #define STK5_CAN_XCVR_GPIO    MX28_PAD_LCD_D00__GPIO_1_0
+ static const struct gpio tx28_gpios[] = {
 -      .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
++      { TX28_USBH_VBUSEN_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "USBH VBUSEN", },
++      { TX28_USBH_OC_GPIO, GPIOFLAG_INPUT, "USBH OC", },
++      { TX28_USBOTG_VBUSEN_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUSEN", },
++      { TX28_USBOTG_OC_GPIO, GPIOFLAG_INPUT, "USBOTG OC", },
++      { TX28_USBOTG_ID_GPIO, GPIOFLAG_INPUT, "USBOTG ID", },
+ };
+ static const iomux_cfg_t tx28_pads[] = {
+       /* UART pads */
+ #if CONFIG_CONS_INDEX == 0
+       MX28_PAD_AUART0_RX__DUART_CTS,
+       MX28_PAD_AUART0_TX__DUART_RTS,
+       MX28_PAD_AUART0_CTS__DUART_RX,
+       MX28_PAD_AUART0_RTS__DUART_TX,
+ #elif CONFIG_CONS_INDEX == 1
+       MX28_PAD_AUART1_RX__AUART1_RX,
+       MX28_PAD_AUART1_TX__AUART1_TX,
+       MX28_PAD_AUART1_CTS__AUART1_CTS,
+       MX28_PAD_AUART1_RTS__AUART1_RTS,
+ #elif CONFIG_CONS_INDEX == 2
+       MX28_PAD_AUART3_RX__AUART3_RX,
+       MX28_PAD_AUART3_TX__AUART3_TX,
+       MX28_PAD_AUART3_CTS__AUART3_CTS,
+       MX28_PAD_AUART3_RTS__AUART3_RTS,
+ #endif
+       /* I2C bus for internal DS1339, PCA9554 and on DIMM pins 40/41 */
+       MX28_PAD_I2C0_SCL__I2C0_SCL,
+       MX28_PAD_I2C0_SDA__I2C0_SDA,
+       /* USBH VBUSEN, OC */
+       MX28_PAD_SPDIF__GPIO_3_27,
+       MX28_PAD_JTAG_RTCK__GPIO_4_20,
+       /* USBOTG VBUSEN, OC, ID */
+       MX28_PAD_GPMI_CE2N__GPIO_0_18,
+       MX28_PAD_GPMI_CE3N__GPIO_0_19,
+       MX28_PAD_PWM2__GPIO_3_18,
+ };
+ /*
+  * Functions
+  */
+ /* provide at least _some_ sort of randomness */
+ #define MAX_LOOPS       100
+ static u32 random;
+ static inline void random_init(void)
+ {
+       struct mxs_digctl_regs *digctl_regs = (void *)MXS_DIGCTL_BASE;
+       u32 seed = 0;
+       int i;
+       for (i = 0; i < MAX_LOOPS; i++) {
+               u32 hclk = readl(&digctl_regs->hw_digctl_hclkcount);
+               u32 entropy = readl(&digctl_regs->hw_digctl_entropy);
+               u32 usec = readl(&digctl_regs->hw_digctl_microseconds);
+               seed = get_timer(hclk ^ entropy ^ usec ^ random ^ seed);
+               srand(seed);
+               random = rand();
+       }
+ }
+ #define RTC_PERSISTENT0_CLK32_MASK    (RTC_PERSISTENT0_CLOCKSOURCE |  \
+                                       RTC_PERSISTENT0_XTAL32KHZ_PWRUP)
+ static u32 boot_cause __attribute__((section("data")));
+ int board_early_init_f(void)
+ {
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       u32 rtc_stat;
+       int timeout = 5000;
+       random_init();
+       /* IO0 clock at 480MHz */
+       mxs_set_ioclk(MXC_IOCLK0, 480000);
+       /* IO1 clock at 480MHz */
+       mxs_set_ioclk(MXC_IOCLK1, 480000);
+       /* SSP0 clock at 96MHz */
+       mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
+       /* SSP2 clock at 96MHz */
+       mxs_set_sspclk(MXC_SSPCLK2, 96000, 0);
+       gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
+       mxs_iomux_setup_multiple_pads(tx28_pads, ARRAY_SIZE(tx28_pads));
+       while ((rtc_stat = readl(&rtc_regs->hw_rtc_stat)) &
+               RTC_STAT_STALE_REGS_PERSISTENT0) {
+               if (timeout-- < 0)
+                       return 1;
+               udelay(1);
+       }
+       boot_cause = readl(&rtc_regs->hw_rtc_persistent0);
+       if ((boot_cause & RTC_PERSISTENT0_CLK32_MASK) !=
+               RTC_PERSISTENT0_CLK32_MASK) {
+               if (boot_cause & RTC_PERSISTENT0_CLOCKSOURCE)
+                       goto rtc_err;
+               writel(RTC_PERSISTENT0_CLK32_MASK,
+                       &rtc_regs->hw_rtc_persistent0_set);
+       }
+       return 0;
+ rtc_err:
+       serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
+       return 1;
+ }
+ int board_init(void)
+ {
+       if (ctrlc()) {
+               printf("CTRL-C detected; safeboot enabled\n");
+               return 1;
+       }
+       /* Address of boot parameters */
+ #ifdef CONFIG_OF_LIBFDT
+       gd->bd->bi_arch_number = -1;
+ #endif
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       return 0;
+ }
+ int dram_init(void)
+ {
+       return mxs_dram_init();
+ }
+ #ifdef        CONFIG_CMD_MMC
+ static int tx28_mmc_wp(int dev_no)
+ {
+       return 0;
+ }
+ int board_mmc_init(bd_t *bis)
+ {
+       return mxsmmc_initialize(bis, 0, tx28_mmc_wp, NULL);
+ }
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_FEC_MXC
+ #ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+ #ifdef CONFIG_FEC_MXC_MULTI
+ #define FEC_MAX_IDX                   1
+ #else
+ #define FEC_MAX_IDX                   0
+ #endif
+ #ifndef ETH_ALEN
+ #define ETH_ALEN                      6
+ #endif
+ static int fec_get_mac_addr(int index)
+ {
+       int timeout = 1000;
+       struct mxs_ocotp_regs *ocotp_regs =
+               (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
+       u32 *cust = &ocotp_regs->hw_ocotp_cust0;
+       u8 mac[ETH_ALEN];
+       char env_name[] = "eth.addr";
+       u32 val = 0;
+       int i;
+       if (index < 0 || index > FEC_MAX_IDX)
+               return -EINVAL;
+       /* set this bit to open the OTP banks for reading */
+       writel(OCOTP_CTRL_RD_BANK_OPEN,
+               &ocotp_regs->hw_ocotp_ctrl_set);
+       /* wait until OTP contents are readable */
+       while (OCOTP_CTRL_BUSY & readl(&ocotp_regs->hw_ocotp_ctrl)) {
+               if (timeout-- < 0)
+                       return -ETIMEDOUT;
+               udelay(100);
+       }
+       for (i = 0; i < sizeof(mac); i++) {
+               int shift = 24 - i % 4 * 8;
+               if (i % 4 == 0)
+                       val = readl(&cust[index * 8 + i]);
+               mac[i] = val >> shift;
+       }
+       if (!is_valid_ether_addr(mac)) {
+               if (index == 0)
+                       printf("No valid MAC address programmed\n");
+               return 0;
+       }
+       if (index == 0) {
+               printf("MAC addr from fuse: %pM\n", mac);
+               snprintf(env_name, sizeof(env_name), "ethaddr");
+       } else {
+               snprintf(env_name, sizeof(env_name), "eth%daddr", index);
+       }
+       eth_setenv_enetaddr(env_name, mac);
+       return 0;
+ }
+ #endif /* CONFIG_GET_FEC_MAC_ADDR_FROM_IIM */
+ static const iomux_cfg_t tx28_fec_pads[] = {
+       MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+       MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+       MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+ };
+ int board_eth_init(bd_t *bis)
+ {
+       int ret;
+       /* Reset the external phy */
+       gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
+       /* Power on the external phy */
+       gpio_direction_output(MX28_PAD_PWM4__GPIO_3_29, 1);
+       /* Pull strap pins to high */
+       gpio_direction_output(MX28_PAD_ENET0_RX_EN__GPIO_4_2, 1);
+       gpio_direction_output(MX28_PAD_ENET0_RXD0__GPIO_4_3, 1);
+       gpio_direction_output(MX28_PAD_ENET0_RXD1__GPIO_4_4, 1);
+       gpio_direction_input(MX28_PAD_ENET0_TX_CLK__GPIO_4_5);
+       udelay(25000);
+       gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+       udelay(100);
+       mxs_iomux_setup_multiple_pads(tx28_fec_pads, ARRAY_SIZE(tx28_fec_pads));
+       ret = cpu_eth_init(bis);
+       if (ret) {
+               printf("cpu_eth_init() failed: %d\n", ret);
+               return ret;
+       }
+ #ifdef CONFIG_FEC_MXC_MULTI
+       if (getenv("ethaddr")) {
+               ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC0\n");
+                       return ret;
+               }
+       }
+       if (getenv("eth1addr")) {
+               ret = fecmxc_initialize_multi(bis, 1, 1, MXS_ENET1_BASE);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC1\n");
+                       return ret;
+               }
+       }
+ #else
+       if (getenv("ethaddr")) {
+               ret = fecmxc_initialize(bis);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC\n");
+                       return ret;
+               }
+       }
+ #endif
+       return 0;
+ }
+ #endif /* CONFIG_FEC_MXC */
+ enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+ };
+ void show_activity(int arg)
+ {
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX28_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX28_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX28_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+ }
+ static const iomux_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX28_PAD_ENET0_RXD3__GPIO_4_10,
+ };
+ static const struct gpio stk5_gpios[] = {
+ };
+ #ifdef CONFIG_LCD
+ static ushort tx28_cmap[256];
+ vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
 -      { TX28_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
 -      { TX28_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
 -      { TX28_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
++      .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx28_cmap,
+ };
+ static struct fb_videomode tx28_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+ };
+ static int lcd_enabled = 1;
+ static int lcd_bl_polarity;
+ static int lcd_backlight_polarity(void)
+ {
+       return lcd_bl_polarity;
+ }
+ void lcd_enable(void)
+ {
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+       karo_load_splashimage(1);
+       if (lcd_enabled) {
+               debug("Switching LCD on\n");
+               gpio_set_value(TX28_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX28_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX28_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+ }
+ void lcd_disable(void)
+ {
+ }
+ void lcd_panel_disable(void)
+ {
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX28_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX28_LCD_RST_GPIO, 0);
+               gpio_set_value(TX28_LCD_PWR_GPIO, 0);
+       }
+ }
+ static const iomux_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
+       /* LCD POWER_ENABLE */
+       MX28_PAD_LCD_ENABLE__GPIO_1_31 | MXS_PAD_CTRL,
+       /* LCD Backlight (PWM) */
+       MX28_PAD_PWM0__GPIO_3_16 | MXS_PAD_CTRL,
+       /* Display */
+       MX28_PAD_LCD_D00__LCD_D0 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D01__LCD_D1 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D02__LCD_D2 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D03__LCD_D3 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D04__LCD_D4 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D05__LCD_D5 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D06__LCD_D6 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D07__LCD_D7 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D08__LCD_D8 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D09__LCD_D9 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D10__LCD_D10 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D11__LCD_D11 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D12__LCD_D12 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D13__LCD_D13 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D14__LCD_D14 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D15__LCD_D15 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D16__LCD_D16 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D17__LCD_D17 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D18__LCD_D18 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D19__LCD_D19 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D20__LCD_D20 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D21__LCD_D21 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D22__LCD_D22 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D23__LCD_D23 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_RD_E__LCD_VSYNC | MXS_PAD_CTRL,
+       MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MXS_PAD_CTRL,
+       MX28_PAD_LCD_RS__LCD_DOTCLK | MXS_PAD_CTRL,
+       MX28_PAD_LCD_CS__LCD_CS | MXS_PAD_CTRL,
+ };
+ static const struct gpio stk5_lcd_gpios[] = {
 -              panel_info.vl_bpix = LCD_COLOR24;
++      { TX28_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
++      { TX28_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
++      { TX28_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ extern void video_hw_init(void *lcdbase);
+ void lcd_ctrl_init(void *lcdbase)
+ {
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = tx28_fb_modes;
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+       if (had_ctrlc()) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 8:
+                                       case 16:
+                                       case 18:
+                                       case 24:
+                                               color_depth = val;
+                                               break;
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx28_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
 -      gpio_request_one(STK5_CAN_XCVR_GPIO, GPIOF_OUTPUT_INIT_HIGH,
++              panel_info.vl_bpix = LCD_COLOR32;
+       }
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+       if (p != &fb_mode) {
+               int ret;
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       mxs_iomux_setup_multiple_pads(stk5_lcd_pads,
+                               ARRAY_SIZE(stk5_lcd_pads));
+       debug("video format: %ux%u-%u@%u\n", p->xres, p->yres,
+               color_depth, refresh);
+       if (karo_load_splashimage(0) == 0) {
+               char vmode[128];
+               /* setup env variable for mxsfb display driver */
+               snprintf(vmode, sizeof(vmode),
+                       "x:%d,y:%d,le:%d,ri:%d,up:%d,lo:%d,hs:%d,vs:%d,sync:%d,pclk:%d,depth:%d",
+                       p->xres, p->yres, p->left_margin, p->right_margin,
+                       p->upper_margin, p->lower_margin, p->hsync_len,
+                       p->vsync_len, p->sync, p->pixclock, color_depth);
+               setenv("videomode", vmode);
+               debug("Initializing LCD controller\n");
+               video_hw_init(lcdbase);
+               setenv("videomode", NULL);
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+ }
+ #else
+ #define lcd_enabled 0
+ #endif /* CONFIG_LCD */
+ static void stk5_board_init(void)
+ {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       mxs_iomux_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+ }
+ static void stk5v3_board_init(void)
+ {
+       stk5_board_init();
+ }
+ static void stk5v5_board_init(void)
+ {
+       stk5_board_init();
+       /* init flexcan transceiver enable GPIO */
 -      mxs_iomux_setup_pad(STK5_CAN_XCVR_GPIO);
++      gpio_request_one(STK5_CAN_XCVR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
 -void ft_board_setup(void *blob, bd_t *bd)
++      SETUP_IOMUX_PAD(STK5_CAN_XCVR_GPIO);
+ }
+ int tx28_fec1_enabled(void)
+ {
+       const char *status;
+       int off;
+       if (!gd->fdt_blob)
+               return 0;
+       off = fdt_path_offset(gd->fdt_blob, "ethernet1");
+       if (off < 0)
+               return 0;
+       status = fdt_getprop(gd->fdt_blob, off, "status", NULL);
+       return status && (strcmp(status, "okay") == 0);
+ }
+ static void tx28_init_mac(void)
+ {
+       int ret;
+       ret = fec_get_mac_addr(0);
+       if (ret < 0) {
+               printf("Failed to read FEC0 MAC address from OCOTP\n");
+               return;
+       }
+ #ifdef CONFIG_FEC_MXC_MULTI
+       if (tx28_fec1_enabled()) {
+               ret = fec_get_mac_addr(1);
+               if (ret < 0) {
+                       printf("Failed to read FEC1 MAC address from OCOTP\n");
+                       return;
+               }
+       }
+ #endif
+ }
+ int board_late_init(void)
+ {
+       int ret = 0;
+       const char *baseboard;
+       env_cleanup();
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else
+               karo_fdt_move_fdt();
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+       printf("Baseboard: %s\n", baseboard);
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+ exit:
+       tx28_init_mac();
+       clear_ctrlc();
+       return ret;
+ }
+ #define BOOT_CAUSE_MASK               (RTC_PERSISTENT0_EXTERNAL_RESET |       \
+                               RTC_PERSISTENT0_ALARM_WAKE |            \
+                               RTC_PERSISTENT0_THERMAL_RESET)
+ static void thermal_init(void)
+ {
+       struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+       struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+       writel(POWER_THERMAL_LOW_POWER | POWER_THERMAL_OFFSET_ADJ_ENABLE |
+               POWER_THERMAL_OFFSET_ADJ_OFFSET(3),
+               &power_regs->hw_power_thermal);
+       writel(CLKCTRL_RESET_EXTERNAL_RESET_ENABLE |
+               CLKCTRL_RESET_THERMAL_RESET_ENABLE,
+               &clkctrl_regs->hw_clkctrl_reset);
+ }
+ int checkboard(void)
+ {
+       struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+       u32 pwr_sts = readl(&power_regs->hw_power_sts);
+       u32 pwrup_src = (pwr_sts >> 24) & 0x3f;
+       const char *dlm = "";
+       printf("Board: Ka-Ro TX28-4%sx%d\n", TX28_MOD_SUFFIX,
+               CONFIG_SDRAM_SIZE / SZ_128M +
+               CONFIG_SYS_NAND_BLOCKS / 2048 * 2);
+       printf("POWERUP Source: ");
+       if (pwrup_src & (3 << 0)) {
+               printf("%sPSWITCH %s voltage", dlm,
+                       pwrup_src & (1 << 1) ? "HIGH" : "MID");
+               dlm = " | ";
+       }
+       if (pwrup_src & (1 << 4)) {
+               printf("%sRTC", dlm);
+               dlm = " | ";
+       }
+       if (pwrup_src & (1 << 5)) {
+               printf("%s5V", dlm);
+               dlm = " | ";
+       }
+       printf("\n");
+       if (boot_cause & BOOT_CAUSE_MASK) {
+               dlm="";
+               printf("Last boot cause: ");
+               if (boot_cause & RTC_PERSISTENT0_EXTERNAL_RESET) {
+                       printf("%sEXTERNAL", dlm);
+                       dlm = " | ";
+               }
+               if (boot_cause & RTC_PERSISTENT0_THERMAL_RESET) {
+                       printf("%sTHERMAL", dlm);
+                       dlm = " | ";
+               }
+               if (*dlm != '\0')
+                       printf(" RESET");
+               if (boot_cause & RTC_PERSISTENT0_ALARM_WAKE) {
+                       printf("%sALARM WAKE", dlm);
+                       dlm = " | ";
+               }
+               printf("\n");
+       }
+       while (pwr_sts & POWER_STS_THERMAL_WARNING) {
+               static int first = 1;
+               if (first) {
+                       printf("CPU too hot to boot\n");
+                       first = 0;
+               }
+               if (tstc())
+                       break;
+               pwr_sts = readl(&power_regs->hw_power_sts);
+       }
+       if (!(boot_cause & RTC_PERSISTENT0_THERMAL_RESET))
+               thermal_init();
+       return 0;
+ }
+ #if defined(CONFIG_OF_BOARD_SETUP)
+ #ifdef CONFIG_FDT_FIXUP_PARTITIONS
+ #include <jffs2/jffs2.h>
+ #include <mtd_node.h>
+ static struct node_info tx28_nand_nodes[] = {
+       { "fsl,imx28-gpmi-nand", MTD_DEV_TYPE_NAND, },
+ };
+ #else
+ #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+ #endif
+ static const char *tx28_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "fsl,imx28-lradc",
+ };
 -      if (ret)
++int ft_board_setup(void *blob, bd_t *bd)
+ {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+       ret = fdt_increase_size(blob, 4096);
 -
++      if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
++              return ret;
++      }
+ #ifdef CONFIG_TX28_S
+       /* TX28-41xx (aka TX28S) has no external RTC
+        * and no I2C GPIO extender
+        */
+       karo_fdt_remove_node(blob, "ds1339");
+       karo_fdt_remove_node(blob, "gpio5");
+ #endif
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+       fdt_fixup_mtdparts(blob, tx28_nand_nodes, ARRAY_SIZE(tx28_nand_nodes));
+       fdt_fixup_ethernet(blob);
+       karo_fdt_fixup_touchpanel(blob, tx28_touchpanels,
+                               ARRAY_SIZE(tx28_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       karo_fdt_update_fb_mode(blob, video_mode);
++
++      return 0;
+ }
+ #endif /* CONFIG_OF_BOARD_SETUP */
diff --combined board/karo/tx48/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ea17d4c87b4d39fe8721ca163194b06ea889e12a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++if TARGET_TX48
++
++config SYS_BOARD
++      default "tx48"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "am33xx"
++
++config SYS_CONFIG_NAME
++      default "tx48"
++
++endif
diff --combined board/karo/tx48/Makefile
index 0000000000000000000000000000000000000000,685af9de56d6b5eb11664fb717049597ce0947bb..405e8ca315357f21bf4349324fe9e391fae3b837
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,46 +1,11 @@@
 -# Makefile
+ #
 -# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# This program is free software; you can redistribute it and/or
 -# modify it under the terms of the GNU General Public License as
 -# published by the Free Software Foundation version 2.
 -#
 -# This program is distributed "as is" WITHOUT ANY WARRANTY of any
 -# kind, whether express or implied; without even the implied warranty
 -# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 -# GNU General Public License for more details.
 -#
 -
 -include $(TOPDIR)/config.mk
++# SPDX-License-Identifier:    GPL-2.0+
+ #
 -LIB   = $(obj)lib$(BOARD).o
 -
 -ifeq ($(CONFIG_SPL_BUILD),)
 -      COBJS   := tx48.o
 -      COBJS   := spl.o
++ifneq ($(CONFIG_SPL_BUILD),y)
++      obj-y                   += tx48.o
+ else
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -SOBJS := $(addprefix $(obj),$(SOBJS))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -clean:
 -      rm -f $(SOBJS) $(OBJS)
 -
 -distclean:    clean
 -      rm -f $(LIB) core *.bak $(obj).depend
 -
 -#########################################################################
 -
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
++      obj-y                   += spl.o
+ endif
diff --combined board/karo/tx48/spl.c
index 0000000000000000000000000000000000000000,1b17586bde777dbf1ee445d7a606b292ee219194..2d71d498d9d90189ec19cd61d692a8912e2c5cb9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,737 +1,737 @@@
 -      { TX48_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ /*
+  * board/karo/tx48/spl.c
+  * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License as
+  * published by the Free Software Foundation version 2.
+  *
+  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+  * kind, whether express or implied; without even the implied warranty
+  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  * GNU General Public License for more details.
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <miiphy.h>
+ #include <netdev.h>
+ #include <serial.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <nand.h>
+ #include <net.h>
+ #include <spl.h>
+ #include <linux/mtd/nand.h>
+ #include <asm/gpio.h>
+ #include <asm/cache.h>
+ #include <asm/omap_common.h>
+ #include <asm/io.h>
+ #include <asm/arch/cpu.h>
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/mmc_host_def.h>
+ #include <asm/arch/ddr_defs.h>
+ #include <asm/arch/sys_proto.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/mem.h>
+ #include <video_fb.h>
+ #include <asm/arch/da8xx-fb.h>
+ #include "flash.h"
+ #define TX48_LED_GPIO         AM33XX_GPIO_NR(1, 26)
+ #define TX48_ETH_PHY_RST_GPIO AM33XX_GPIO_NR(3, 8)
+ #define TX48_LCD_RST_GPIO     AM33XX_GPIO_NR(1, 19)
+ #define TX48_LCD_PWR_GPIO     AM33XX_GPIO_NR(1, 22)
+ #define TX48_LCD_BACKLIGHT_GPIO       AM33XX_GPIO_NR(3, 14)
+ #define GMII_SEL              (CTRL_BASE + 0x650)
+ /* UART Defines */
+ #define UART_SYSCFG_OFFSET    0x54
+ #define UART_SYSSTS_OFFSET    0x58
+ #define UART_RESET            (0x1 << 1)
+ #define UART_RESETDONE                (1 << 0)
+ #define UART_IDLE_MODE(m)     (((m) << 3) & UART_IDLE_MODE_MASK)
+ #define UART_IDLE_MODE_MASK   (0x3 << 3)
+ /* Timer Defines */
+ #define TSICR_REG             0x54
+ #define TIOCP_CFG_REG         0x10
+ #define TCLR_REG              0x38
+ /* RGMII mode define */
+ #define RGMII_MODE_ENABLE     0xA
+ #define RMII_MODE_ENABLE      0x5
+ #define MII_MODE_ENABLE               0x0
+ #define NO_OF_MAC_ADDR                1
+ #define ETH_ALEN              6
+ /* PAD Control Fields */
+ #define SLEWCTRL      (0x1 << 6)
+ #define       RXACTIVE        (0x1 << 5)
+ #define       PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
+ #define PULLUDEN      (0x0 << 3) /* Pull up enabled */
+ #define PULLUDDIS     (0x1 << 3) /* Pull up disabled */
+ #define MODE(val)     (val)
+ DECLARE_GLOBAL_DATA_PTR;
+ /*
+  * PAD CONTROL OFFSETS
+  * Field names corresponds to the pad signal name
+  */
+ struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+ };
+ struct pin_mux {
+       short reg_offset;
+       uint8_t val;
+ };
+ #define PAD_CTRL_BASE 0x800
+ #define OFFSET(x)     (unsigned int) (&((struct pad_signals *) \
+                               (PAD_CTRL_BASE))->x)
+ static struct pin_mux tx48_pins[] = {
+ #ifdef CONFIG_CMD_NAND
+       { OFFSET(gpmc_ad0), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD0 */
+       { OFFSET(gpmc_ad1), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD1 */
+       { OFFSET(gpmc_ad2), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD2 */
+       { OFFSET(gpmc_ad3), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD3 */
+       { OFFSET(gpmc_ad4), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD4 */
+       { OFFSET(gpmc_ad5), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD5 */
+       { OFFSET(gpmc_ad6), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD6 */
+       { OFFSET(gpmc_ad7), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD7 */
+       { OFFSET(gpmc_wait0), MODE(0) | RXACTIVE | PULLUP_EN, }, /* NAND WAIT */
+       { OFFSET(gpmc_wpn), MODE(7) | PULLUP_EN | RXACTIVE, },  /* NAND_WPN */
+       { OFFSET(gpmc_csn0), MODE(0) | PULLUDEN, },     /* NAND_CS0 */
+       { OFFSET(gpmc_advn_ale), MODE(0) | PULLUDEN, }, /* NAND_ADV_ALE */
+       { OFFSET(gpmc_oen_ren), MODE(0) | PULLUDEN, },  /* NAND_OE */
+       { OFFSET(gpmc_wen), MODE(0) | PULLUDEN, },      /* NAND_WEN */
+       { OFFSET(gpmc_be0n_cle), MODE(0) | PULLUDEN, }, /* NAND_BE_CLE */
+ #endif
+       /* I2C0 */
+       { OFFSET(i2c0_sda), MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL, }, /* I2C_DATA */
+       { OFFSET(i2c0_scl), MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL, }, /* I2C_SCLK */
+ #ifndef CONFIG_NO_ETH
+       /* RMII1 */
+       { OFFSET(mii1_crs), MODE(1) | RXACTIVE, },      /* RMII1_CRS */
+       { OFFSET(mii1_rxerr), MODE(1) | RXACTIVE | PULLUDEN, },  /* RMII1_RXERR */
+       { OFFSET(mii1_txen), MODE(1), },                     /* RMII1_TXEN */
+       { OFFSET(mii1_txd1), MODE(1), },                     /* RMII1_TXD1 */
+       { OFFSET(mii1_txd0), MODE(1), },                     /* RMII1_TXD0 */
+       { OFFSET(mii1_rxd1), MODE(1) | RXACTIVE | PULLUP_EN, }, /* RMII1_RXD1 */
+       { OFFSET(mii1_rxd0), MODE(1) | RXACTIVE | PULLUP_EN, }, /* RMII1_RXD0 */
+       { OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN, }, /* MDIO_DATA */
+       { OFFSET(mdio_clk), MODE(0) | PULLUP_EN, },     /* MDIO_CLK */
+       { OFFSET(rmii1_refclk), MODE(0) | RXACTIVE, },  /* RMII1_REFCLK */
+       { OFFSET(emu0), MODE(7) | RXACTIVE},         /* nINT */
+       { OFFSET(emu1), MODE(7), },                  /* nRST */
+ #endif
+ };
+ static struct gpio tx48_gpios[] = {
+       /* configure this pin early to prevent flicker of the LCD */
++      { TX48_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ static struct pin_mux tx48_mmc_pins[] = {
+ #ifdef CONFIG_OMAP_HSMMC
+       /* MMC1 */
+       { OFFSET(mii1_rxd2), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT3 */
+       { OFFSET(mii1_rxd3), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT2 */
+       { OFFSET(mii1_rxclk), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT1 */
+       { OFFSET(mii1_txclk), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT0 */
+       { OFFSET(gpmc_csn1), MODE(2) | RXACTIVE | PULLUP_EN, }, /* MMC1_CLK */
+       { OFFSET(gpmc_csn2), MODE(2) | RXACTIVE | PULLUP_EN, }, /* MMC1_CMD */
+       { OFFSET(mcasp0_fsx), MODE(4) | RXACTIVE, },    /* MMC1_CD */
+ #endif
+ };
+ /*
+  * Configure the pin mux for the module
+  */
+ static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
+                       int num_pins)
+ {
+       int i;
+       for (i = 0; i < num_pins; i++)
+               writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
+ }
+ static struct pin_mux tx48_uart0_pins[] = {
+ #ifdef CONFIG_SYS_NS16550_COM1
+       /* UART0 for early boot messages */
+       { OFFSET(uart0_rxd), MODE(0) | PULLUP_EN | RXACTIVE, }, /* UART0_RXD */
+       { OFFSET(uart0_txd), MODE(0) | PULLUDEN, },             /* UART0_TXD */
+       { OFFSET(uart0_ctsn), MODE(0) | PULLUP_EN | RXACTIVE, },/* UART0_CTS */
+       { OFFSET(uart0_rtsn), MODE(0) | PULLUDEN, },            /* UART0_RTS */
+ #endif
+ #ifdef CONFIG_SYS_NS16550_COM2
+       /* UART1 */
+       { OFFSET(uart1_rxd), MODE(0) | PULLUP_EN | RXACTIVE, }, /* UART1_RXD */
+       { OFFSET(uart1_txd), MODE(0) | PULLUDEN, },             /* UART1_TXD */
+       { OFFSET(uart1_ctsn), MODE(0) | PULLUP_EN | RXACTIVE, },/* UART1_CTS */
+       { OFFSET(uart1_rtsn), MODE(0) | PULLUDEN, },            /* UART1_RTS */
+ #endif
+ #ifdef CONFIG_SYS_NS16550_COM3
+       /* UART5 */
+       { OFFSET(mii1_rxdv), MODE(3) | PULLUP_EN | RXACTIVE, }, /* UART5_RXD */
+       { OFFSET(mii1_col), MODE(3) | PULLUDEN, },              /* UART5_TXD */
+       { OFFSET(mmc0_dat1), MODE(2) | PULLUP_EN | RXACTIVE, }, /* UART5_CTS */
+       { OFFSET(mmc0_dat0), MODE(2) | PULLUDEN, },             /* UART5_RTS */
+ #endif
+ };
+ /*
+  * early system init of muxing and clocks.
+  */
+ static void enable_uart0_pin_mux(void)
+ {
+       tx48_set_pin_mux(tx48_uart0_pins, ARRAY_SIZE(tx48_uart0_pins));
+ }
+ static void enable_mmc0_pin_mux(void)
+ {
+       tx48_set_pin_mux(tx48_mmc_pins, ARRAY_SIZE(tx48_mmc_pins));
+ }
+ static const u32 gpmc_nand_cfg[GPMC_MAX_REG] = {
+       TX48_NAND_GPMC_CONFIG1,
+       TX48_NAND_GPMC_CONFIG2,
+       TX48_NAND_GPMC_CONFIG3,
+       TX48_NAND_GPMC_CONFIG4,
+       TX48_NAND_GPMC_CONFIG5,
+       TX48_NAND_GPMC_CONFIG6,
+ };
+ #define SDRAM_CLK             CONFIG_SYS_DDR_CLK
+ #define ns_TO_ck(ns)          (((ns) * SDRAM_CLK + 999) / 1000)
+ #define ck_TO_ns(ck)          ((ck) * 1000 / SDRAM_CLK)
+ #ifdef DEBUG
+ static inline unsigned ck_val_check(unsigned ck, unsigned offs, unsigned max,
+                       const char *name)
+ {
+       if (ck < offs) {
+               printf("value %u for parameter %s is out of range (min: %u\n",
+                       ck, name, offs);
+               hang();
+       }
+       if (ck > max) {
+               printf("value %u for parameter %s is out of range (max: %u\n",
+                       ck, name, max);
+               hang();
+       }
+       return ck - offs;
+ }
+ #define CK_VAL(ck, offs, max) ck_val_check(ck, offs, max, #ck)
+ #else
+ #define CK_VAL(ck, offs, max) ((ck) - (offs))
+ #endif
+ #define DDR3_NT5CB128         1
+ #define DDR3_H5TQ2G8          2
+ #if 1
+ #define SDRAM_TYPE DDR3_NT5CB128
+ #else
+ #define SDRAM_TYPE DDR3_H5TQ2G8
+ #endif
+ #ifndef SDRAM_TYPE
+ #error No SDRAM_TYPE specified
+ #elif (SDRAM_TYPE == DDR3_NT5CB128) || (SDRAM_TYPE == DDR3_H5TQ2G8)
+ #define tRP                   ns_TO_ck(14)
+ #define tRCD                  ns_TO_ck(14)
+ #define tWR                   ns_TO_ck(15)
+ #define tRAS                  ns_TO_ck(35)
+ #define tRC                   ns_TO_ck(49)
+ #define tRRD                  max(ns_TO_ck(8), 4)
+ #define tWTR                  max(ns_TO_ck(8), 4)
+ #define tXP                   max(ns_TO_ck(6), 3)
+ #define tXPR                  max(5, ns_TO_ck(ck_TO_ns(tRFC + 1) + 10))
+ #define tODT                  ns_TO_ck(9)
+ #define tXSNR                 max(5, ns_TO_ck(ck_TO_ns(tRFC + 1) + 10))
+ #define tXSRD                 512
+ #define tRTP                  max(ns_TO_ck(8), 4)
+ #define tCKE                  max(ns_TO_ck(6), 3)
+ #define tPDLL_UL              512
+ #define tZQCS                 64
+ #define tRFC                  ns_TO_ck(160)
+ #define tRAS_MAX              0xf
+ static inline int cwl(u32 sdram_clk)
+ {
+       if (sdram_clk <= 300)
+               return 5;
+       else if (sdram_clk > 300 && sdram_clk <= 333)
+               return 5;
+       else if (sdram_clk > 333 && sdram_clk <= 400)
+               return 5;
+       else if (sdram_clk > 400 && sdram_clk <= 533)
+               return 6;
+       else if (sdram_clk > 533 && sdram_clk <= 666)
+               return 7;
+       else if (SDRAM_TYPE != DDR3_H5TQ2G8)
+               ;
+       else if (sdram_clk > 666 && sdram_clk <= 800)
+               return 8;
+       printf("SDRAM clock out of range\n");
+       hang();
+ }
+ #define CWL cwl(SDRAM_CLK)
+ static inline int cl(u32 sdram_clk)
+ {
+       if (sdram_clk <= 300)
+               return 5;
+       else if (sdram_clk > 300 && sdram_clk <= 333)
+               return 5;
+       else if (sdram_clk > 333 && sdram_clk <= 400)
+               return 6;
+       else if (sdram_clk > 400 && sdram_clk <= 533)
+               return 8;
+       else if (sdram_clk > 533 && sdram_clk <= 666)
+               return (SDRAM_TYPE == DDR3_H5TQ2G8) ? 10 : 9;
+       else if (SDRAM_TYPE != DDR3_H5TQ2G8)
+               ;
+       else if (sdram_clk > 666 && sdram_clk <= 800)
+               return 11;
+       printf("SDRAM clock out of range\n");
+       hang();
+ }
+ #define CL cl(SDRAM_CLK)
+ #define ROW_ADDR_BITS         14
+ #define SDRAM_PG_SIZE         1024
+ #else
+ #error Unsupported SDRAM_TYPE specified
+ #endif
+ #define SDRAM_CONFIG_VAL      (                                       \
+               (3 << 29) /* SDRAM type: 0: DDR1 1: LPDDR1 2: DDR2 3: DDR3 */ | \
+               (0 << 27) /* IBANK pos */ |                             \
+               (2 << 24) /* termination resistor value 0: disable 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */ | \
+               (0 << 23) /* DDR2 differential DQS */ |                 \
+               (1 << 21) /* dynamic ODT 0: off 1: RZQ/4 2: RZQ/2 */ |  \
+               (0 << 20) /* DLL disable */ |                           \
+               (1 << 18) /* drive strength 0: RZQ/6 1: RZQ/7 */ |      \
+               ((CWL - 5) << 16) /* CWL 0: 5 ... 3: 8 */ |             \
+               (1 << 14) /* SDRAM data bus width 0: 32 1: 16 */ |      \
+               (((CL - 4) * 2) << 10) /* CAS latency 2: 5 4: 6 6: 8 ... 14: 11 (DDR3) */ | \
+               ((ROW_ADDR_BITS - 9) << 7) /* # of row addr bits 0: 9 ... 7: 16 */ | \
+               (3 << 4) /* # of SDRAM internal banks 0: 1 1: 2 2: 4 3: 8 */ | \
+               (0 << 3) /* # of CS lines */ |                          \
+               ((ffs(SDRAM_PG_SIZE / 256) - 1) << 0) /* page size 0: 256 1: 512 2: 1024 3:2048 */ | \
+               0)
+ #define SDREF_VAL             (                                       \
+               (0 << 31) /* */ |                                       \
+               (1 << 29) /* self refresh temperature range 1: extended temp range */ | \
+               (0 << 28) /* auto self refresh enable */ |              \
+               (0 << 24) /* partial array self refresh */ |            \
+               ((SDRAM_CLK * 7800 / 1000) << 0) /* refresh interval */ | \
+               0)
+ #define tFAW          ns_TO_ck(45)
+ #define SDRAM_TIM1_VAL        ((CK_VAL(tRP, 1, 16) << 25) |   \
+                        (CK_VAL(tRCD, 1, 16) << 21) |  \
+                        (CK_VAL(tWR, 1, 16) << 17) |   \
+                        (CK_VAL(tRAS, 1, 32) << 12) |  \
+                        (CK_VAL(tRC, 1, 64) << 6) |    \
+                        (CK_VAL(tRRD, 1, 8) << 3) |    \
+                        (CK_VAL(tWTR, 1, 8) << 0))
+ #define SDRAM_TIM2_VAL        ((CK_VAL(max(tCKE, tXP), 1, 8) << 28) | \
+                        (CK_VAL(tODT, 0, 8) << 25) |           \
+                        (CK_VAL(tXSNR, 1, 128) << 16) |        \
+                        (CK_VAL(tXSRD, 1, 1024) << 6) |        \
+                        (CK_VAL(tRTP, 1, 8) << 3) |            \
+                        (CK_VAL(tCKE, 1, 8) << 0))
+ #define SDRAM_TIM3_VAL        ((CK_VAL(DIV_ROUND_UP(tPDLL_UL, 128), 0, 16) << 28) | \
+                        (CK_VAL(tZQCS, 1, 64) << 15) |                 \
+                        (CK_VAL(tRFC, 1, 1024) << 4) |                 \
+                        (CK_VAL(tRAS_MAX, 0, 16) << 0))
+ #define ZQ_CONFIG_VAL         (                                       \
+               (1 << 31) /* ZQ calib for CS1 */ |                      \
+               (0 << 30) /* ZQ calib for CS0 */ |                      \
+               (0 << 29) /* dual calib */ |                            \
+               (1 << 28) /* ZQ calib on SR/PWDN exit */ |              \
+               (2 << 18) /* ZQCL intervals for ZQINIT */ |             \
+               (4 << 16) /* ZQCS intervals for ZQCL */ |               \
+               (80 << 0) /* refr periods between ZQCS commands */ |    \
+               0)
+ static struct ddr_data tx48_ddr3_data = {
+       /* reset defaults */
+       .datardsratio0 = 0x04010040,
+       .datawdsratio0 = 0x0,
+       .datafwsratio0 = 0x0,
+       .datawrsratio0 = 0x04010040,
+       .datadldiff0 = 0x4,
+ };
+ static struct cmd_control tx48_ddr3_cmd_ctrl_data = {
+       /* reset defaults */
+       .cmd0csratio = 0x80,
+       .cmd0dldiff = 0x04,
+       .cmd1csratio = 0x80,
+       .cmd1dldiff = 0x04,
+       .cmd2csratio = 0x80,
+       .cmd2dldiff = 0x04,
+ };
+ static void ddr3_calib_start(void)
+ {
+       static struct emif_reg_struct *emif_reg = (void *)EMIF4_0_CFG_BASE;
+       int loops = 0;
+       u32 regval;
+       u32 emif_status;
+       debug("Starting DDR3 calibration\n");
+       /* wait for DDR PHY ready */
+       while (!((emif_status = readl(&emif_reg->emif_status)) & (1 << 2))) {
+               if (loops++ > 100000)
+                       break;
+               udelay(1);
+       }
+       debug("EMIF status: %08x after %u loops\n", emif_status, loops);
+       /* enable DDR3 write levelling */
+       loops = 0;
+       writel(EMIF_REG_RDWRLVLFULL_START_MASK, &emif_reg->emif_rd_wr_lvl_ctl);
+       do {
+               regval = readl(&emif_reg->emif_rd_wr_lvl_ctl);
+               if (!(regval & EMIF_REG_RDWRLVLFULL_START_MASK))
+                       break;
+               udelay(1);
+       } while (loops++ < 100000);
+       if (regval & EMIF_REG_RDWRLVLFULL_START_MASK) {
+               printf("Full WRLVL timed out\n");
+       } else {
+               debug("Full Write Levelling done after %u us\n", loops);
+       }
+       writel(0, &emif_reg->emif_rd_wr_lvl_rmp_ctl);
+       writel(0, &emif_reg->emif_rd_wr_lvl_rmp_win);
+       writel(0x0f808080, &emif_reg->emif_rd_wr_lvl_ctl);
+       debug("DDR3 calibration done\n");
+ }
+ static void tx48_ddr_init(void)
+ {
+       struct emif_regs r = {0};
+       debug("Initialising SDRAM timing for %u MHz DDR clock\n", SDRAM_CLK);
+       r.sdram_config = SDRAM_CONFIG_VAL;
+       r.ref_ctrl = SDREF_VAL;
+       r.sdram_tim1 = SDRAM_TIM1_VAL;
+       r.sdram_tim2 = SDRAM_TIM2_VAL;
+       r.sdram_tim3 = SDRAM_TIM3_VAL;
+       r.zq_config = ZQ_CONFIG_VAL;
+       r.emif_ddr_phy_ctlr_1 = 0x0000030b;
+       config_ddr(SDRAM_CLK, 0x04, &tx48_ddr3_data,
+               &tx48_ddr3_cmd_ctrl_data, &r, 0);
+       ddr3_calib_start();
+       debug("%s: config_ddr done\n", __func__);
+ }
+ #ifdef CONFIG_HW_WATCHDOG
+ static inline void tx48_wdog_disable(void)
+ {
+ }
+ #else
+ static inline void tx48_wdog_disable(void)
+ {
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+       /* WDT1 is already running when the bootloader gets control
+        * Disable it to avoid "random" resets
+        */
+       writel(0xAAAA, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+ }
+ #endif
+ void s_init(void)
+ {
+       struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+       struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+       int timeout = 1000;
+       gd = &gdata;
+       /*
+          * Save the boot parameters passed from romcode.
+          * We cannot delay the saving further than this,
+          * to prevent overwrites.
+          */
+       save_omap_boot_params();
+       /* Setup the PLLs and the clocks for the peripherals */
+       pll_init();
+       tx48_wdog_disable();
+       enable_uart0_pin_mux();
+       /* UART softreset */
+       writel(readl(&uart_base->uartsyscfg) | UART_RESET,
+               &uart_base->uartsyscfg);
+       while (!(readl(&uart_base->uartsyssts) & UART_RESETDONE)) {
+               udelay(1);
+               if (timeout-- <= 0)
+                       break;
+       }
+       /* Disable smart idle */
+       writel((readl(&uart_base->uartsyscfg) & ~UART_IDLE_MODE_MASK) |
+               UART_IDLE_MODE(1), &uart_base->uartsyscfg);
+       preloader_console_init();
+       if (timeout <= 0)
+               printf("Timeout waiting for UART RESET\n");
+       timer_init();
+       tx48_ddr_init();
+       gpmc_init();
+       enable_gpmc_cs_config(gpmc_nand_cfg, &gpmc_cfg->cs[0],
+                       CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_SIZE);
+       /* Enable MMC0 */
+       enable_mmc0_pin_mux();
+       gpio_request_array(tx48_gpios, ARRAY_SIZE(tx48_gpios));
+       tx48_set_pin_mux(tx48_pins, ARRAY_SIZE(tx48_pins));
+ }
diff --combined board/karo/tx48/tx48.c
index 0000000000000000000000000000000000000000,8bc8bc51a6df9e489a11a42e42130293533c07be..da17a32f54c4dd1d0dea5f6edf2e8fd46bc5f971
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1168 +1,1171 @@@
 -      { AM33XX_GPIO_NR(3, 5), GPIOF_INPUT, "I2C1_SDA", },
 -      { AM33XX_GPIO_NR(3, 6), GPIOF_INPUT, "I2C1_SCL", },
 -      { AM33XX_GPIO_NR(3, 8), GPIOF_OUTPUT_INIT_LOW, "ETH_PHY_RESET", },
+ /*
+  * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * based on evm.c
+  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * version 2 as published by the Free Software Foundation.
+  *
+  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+  * kind, whether express or implied; without even the implied warranty
+  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  * GNU General Public License for more details.
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <miiphy.h>
+ #include <netdev.h>
+ #include <serial.h>
+ #include <libfdt.h>
+ #include <lcd.h>
+ #include <fdt_support.h>
+ #include <nand.h>
+ #include <net.h>
+ #include <linux/mtd/nand.h>
+ #include <linux/fb.h>
+ #include <asm/gpio.h>
+ #include <asm/cache.h>
+ #include <asm/omap_common.h>
+ #include <asm/io.h>
+ #include <asm/arch/cpu.h>
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/mmc_host_def.h>
+ #include <asm/arch/sys_proto.h>
+ #include <asm/arch/clock.h>
+ #include <video_fb.h>
+ #include <asm/arch/da8xx-fb.h>
+ #include "../common/karo.h"
+ DECLARE_GLOBAL_DATA_PTR;
+ #define TX48_LED_GPIO         AM33XX_GPIO_NR(1, 26)
+ #define TX48_ETH_PHY_RST_GPIO AM33XX_GPIO_NR(3, 8)
+ #define TX48_LCD_RST_GPIO     AM33XX_GPIO_NR(1, 19)
+ #define TX48_LCD_PWR_GPIO     AM33XX_GPIO_NR(1, 22)
+ #define TX48_LCD_BACKLIGHT_GPIO       AM33XX_GPIO_NR(3, 14)
+ #define TX48_MMC_CD_GPIO      AM33XX_GPIO_NR(3, 15)
+ #define GMII_SEL              (CTRL_BASE + 0x650)
+ /* UART Defines */
+ #define UART_SYSCFG_OFFSET    0x54
+ #define UART_SYSSTS_OFFSET    0x58
+ #define UART_RESET            (0x1 << 1)
+ #define UART_CLK_RUNNING_MASK 0x1
+ #define UART_SMART_IDLE_EN    (0x1 << 0x3)
+ /* Timer Defines */
+ #define TSICR_REG             0x54
+ #define TIOCP_CFG_REG         0x10
+ #define TCLR_REG              0x38
+ /* RGMII mode define */
+ #define RGMII_MODE_ENABLE     0xA
+ #define RMII_MODE_ENABLE      0x5
+ #define MII_MODE_ENABLE               0x0
+ #define NO_OF_MAC_ADDR                1
+ #define ETH_ALEN              6
+ /* PAD Control Fields */
+ #define SLEWCTRL      (0x1 << 6)
+ #define       RXACTIVE        (0x1 << 5)
+ #define       PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
+ #define PULLUDEN      (0x0 << 3) /* Pull up enabled */
+ #define PULLUDDIS     (0x1 << 3) /* Pull up disabled */
+ #define MODE(val)     (val)
+ /*
+  * PAD CONTROL OFFSETS
+  * Field names corresponds to the pad signal name
+  */
+ struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+ };
+ struct pin_mux {
+       short reg_offset;
+       uint8_t val;
+ };
+ #define PAD_CTRL_BASE 0x800
+ #define OFFSET(x)     (unsigned int) (&((struct pad_signals *) \
+                               (PAD_CTRL_BASE))->x)
+ /*
+  * Configure the pin mux for the module
+  */
+ static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
+                       int num_pins)
+ {
+       int i;
+       for (i = 0; i < num_pins; i++)
+               writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
+ }
+ #define PRM_RSTST_GLOBAL_COLD_RST     (1 << 0)
+ #define PRM_RSTST_GLOBAL_WARM_SW_RST  (1 << 1)
+ #define PRM_RSTST_WDT1_RST            (1 << 4)
+ #define PRM_RSTST_EXTERNAL_WARM_RST   (1 << 5)
+ #define PRM_RSTST_ICEPICK_RST         (1 << 9)
+ static u32 prm_rstst __attribute__((section(".data")));
+ /*
+  * Basic board specific setup
+  */
+ static const struct pin_mux tx48_pads[] = {
+       { OFFSET(i2c0_sda), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(emu1), MODE(7), }, /* ETH PHY Reset */
+ };
+ static const struct pin_mux tx48_i2c_pads[] = {
+       { OFFSET(i2c0_sda), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+ };
+ static const struct gpio tx48_gpios[] = {
 -      { TX48_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
 -      { TX48_MMC_CD_GPIO, GPIOF_INPUT, "MMC0 CD", },
++      { AM33XX_GPIO_NR(3, 5), GPIOFLAG_INPUT, "I2C1_SDA", },
++      { AM33XX_GPIO_NR(3, 6), GPIOFLAG_INPUT, "I2C1_SCL", },
++      { AM33XX_GPIO_NR(3, 8), GPIOFLAG_OUTPUT_INIT_LOW, "ETH_PHY_RESET", },
+ };
+ static const struct pin_mux stk5_pads[] = {
+       /* heartbeat LED */
+       { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
+       /* LCD RESET */
+       { OFFSET(gpmc_a3), MODE(7) | PULLUDEN, },
+       /* LCD POWER_ENABLE */
+       { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
+       /* LCD Backlight (PWM) */
+       { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
+       /* MMC CD */
+       { OFFSET(mcasp0_fsx), MODE(7) | PULLUDEN | PULLUP_EN, },
+ };
+ static const struct gpio stk5_gpios[] = {
 -      { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
 -      { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
 -      { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
++      { TX48_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
++      { TX48_MMC_CD_GPIO, GPIOFLAG_INPUT, "MMC0 CD", },
+ };
+ static const struct pin_mux stk5_lcd_pads[] = {
+       /* LCD data bus */
+       { OFFSET(lcd_data0), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data1), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data2), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data3), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data4), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data5), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data6), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data7), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data8), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data9), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data10), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data11), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data12), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data13), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data14), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data15), MODE(0) | PULLUDEN, },
+       /* LCD control signals */
+       { OFFSET(lcd_hsync), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_vsync), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_pclk), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
+ };
+ static const struct gpio stk5_lcd_gpios[] = {
 -      { AM33XX_GPIO_NR(0, 22), GPIOF_OUTPUT_INIT_HIGH, "CAN XCVR", },
++      { AM33XX_GPIO_NR(1, 19), GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
++      { AM33XX_GPIO_NR(1, 22), GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
++      { AM33XX_GPIO_NR(3, 14), GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ static const struct pin_mux stk5v5_pads[] = {
+       /* CAN transceiver control */
+       { OFFSET(gpmc_ad8), MODE(7) | PULLUDEN, },
+ };
+ static const struct gpio stk5v5_gpios[] = {
 -      .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
++      { AM33XX_GPIO_NR(0, 22), GPIOFLAG_OUTPUT_INIT_HIGH, "CAN XCVR", },
+ };
+ #ifdef CONFIG_LCD
+ static u16 tx48_cmap[256];
+ vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1366,
+       .vl_row = 768,
 -              panel_info.vl_bpix = LCD_COLOR24;
++      .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx48_cmap,
+ };
+ #define FB_SYNC_OE_LOW_ACT    (1 << 31)
+ #define FB_SYNC_CLK_LAT_FALL  (1 << 30)
+ static struct fb_videomode tx48_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ };
+ void *lcd_base;                       /* Start of framebuffer memory  */
+ void *lcd_console_address;    /* Start of console buffer      */
+ int lcd_color_fg;
+ int lcd_color_bg;
+ short console_col;
+ short console_row;
+ static int lcd_enabled = 1;
+ static int lcd_bl_polarity;
+ static int lcd_backlight_polarity(void)
+ {
+       return lcd_bl_polarity;
+ }
+ void lcd_initcolregs(void)
+ {
+ }
+ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+ {
+ }
+ void lcd_enable(void)
+ {
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+               debug("Switching LCD on\n");
+               gpio_set_value(TX48_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX48_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+ }
+ void lcd_disable(void)
+ {
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               da8xx_fb_disable();
+               lcd_enabled = 0;
+       }
+ }
+ static void tx48_lcd_panel_setup(struct da8xx_panel *p,
+                               struct fb_videomode *fb)
+ {
+       p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
+       p->width = fb->xres;
+       p->hbp = fb->left_margin;
+       p->hsw = fb->hsync_len;
+       p->hfp = fb->right_margin;
+       p->height = fb->yres;
+       p->vbp = fb->upper_margin;
+       p->vsw = fb->vsync_len;
+       p->vfp = fb->lower_margin;
+       p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
+ }
+ void lcd_panel_disable(void)
+ {
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX48_LCD_PWR_GPIO, 0);
+               gpio_set_value(TX48_LCD_RST_GPIO, 0);
+       }
+ }
+ void lcd_ctrl_init(void *lcdbase)
+ {
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx48_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+       karo_fdt_move_fdt();
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 24:
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
 -void ft_board_setup(void *blob, bd_t *bd)
++              panel_info.vl_bpix = LCD_COLOR32;
+       }
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len)
+               / 1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000,
+               PICOS2KHZ(p->pixclock) % 1000);
+       if (p != &fb_mode) {
+               int ret;
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
+       if (karo_load_splashimage(0) == 0) {
+               struct da8xx_panel da8xx_panel = { };
+               debug("Initializing FB driver\n");
+               tx48_lcd_panel_setup(&da8xx_panel, p);
+               da8xx_video_init(&da8xx_panel, color_depth);
+               debug("Initializing LCD controller\n");
+               video_hw_init();
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+ }
+ #else
+ #define lcd_enabled 0
+ #endif /* CONFIG_LCD */
+ static void stk5_board_init(void)
+ {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
+ }
+ static void stk5v3_board_init(void)
+ {
+       stk5_board_init();
+ }
+ static void stk5v5_board_init(void)
+ {
+       stk5_board_init();
+       gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
+       tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
+ }
+ /* called with default environment! */
+ int board_init(void)
+ {
+       int i;
+       /* mach type passed to kernel */
+ #ifdef CONFIG_OF_LIBFDT
+       gd->bd->bi_arch_number = -1;
+ #endif
+       /* address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+       if (ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               if (prm_rstst & PRM_RSTST_WDT1_RST)
+                       printf("WDOG RESET detected\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+       }
+       gpio_request_array(tx48_gpios, ARRAY_SIZE(tx48_gpios));
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_pads));
+       for (i = 0; i < ARRAY_SIZE(tx48_gpios); i++) {
+               int gpio = tx48_gpios[i].gpio;
+               if (gpio_get_value(gpio) == 0)
+                       gpio_direction_output(gpio, 1);
+       }
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_i2c_pads));
+       return 0;
+ }
+ static void show_reset_cause(u32 prm_rstst)
+ {
+       const char *dlm = "";
+       printf("RESET cause: ");
+       if (prm_rstst & PRM_RSTST_GLOBAL_COLD_RST) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_GLOBAL_WARM_SW_RST) {
+               printf("%sSW", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_WDT1_RST) {
+               printf("%sWATCHDOG", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_EXTERNAL_WARM_RST) {
+               printf("%sWARM", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_ICEPICK_RST) {
+               printf("%sJTAG", dlm);
+               dlm = " | ";
+       }
+       if (*dlm == '\0')
+               printf("unknown");
+       printf(" RESET\n");
+ }
+ /* called with default environment! */
+ int checkboard(void)
+ {
+       prm_rstst = readl(PRM_RSTST);
+       show_reset_cause(prm_rstst);
+       printf("Board: Ka-Ro TX48-7020\n");
+       timer_init();
+       return 0;
+ }
+ static void tx48_set_cpu_clock(void)
+ {
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       unsigned long act_cpu_clk;
+       if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
+               return;
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (prm_rstst & PRM_RSTST_WDT1_RST) ?
+                       "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+       mpu_pll_config_val(cpu_clk);
+       act_cpu_clk = mpu_clk_rate();
+       if (cpu_clk * 1000000 != act_cpu_clk) {
+               printf("Failed to set CPU clock to %lu MHz; using %lu.%03lu MHz instead\n",
+                       cpu_clk, act_cpu_clk / 1000000,
+                       act_cpu_clk / 1000 % 1000);
+       } else {
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       act_cpu_clk / 1000000, act_cpu_clk / 1000 % 1000);
+       }
+ }
+ static void tx48_init_mac(void)
+ {
+       uint8_t mac_addr[ETH_ALEN];
+       uint32_t mac_hi, mac_lo;
+       /* try reading mac address from efuse */
+       mac_lo = __raw_readl(MAC_ID0_LO);
+       mac_hi = __raw_readl(MAC_ID0_HI);
+       mac_addr[0] = mac_hi & 0xFF;
+       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       mac_addr[4] = mac_lo & 0xFF;
+       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+       if (!is_valid_ether_addr(mac_addr)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+       printf("MAC addr from fuse: %pM\n", mac_addr);
+       eth_setenv_enetaddr("ethaddr", mac_addr);
+ }
+ /* called with environment from NAND or MMC */
+ int board_late_init(void)
+ {
+       int ret = 0;
+       const char *baseboard;
+       env_cleanup();
+       tx48_set_cpu_clock();
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (prm_rstst & PRM_RSTST_WDT1_RST)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               printf("Baseboard: %s\n", baseboard);
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+ exit:
+       tx48_init_mac();
+       clear_ctrlc();
+       return ret;
+ }
+ #ifdef CONFIG_DRIVER_TI_CPSW
+ static void tx48_phy_init(void)
+ {
+       debug("%s: Resetting ethernet PHY\n", __func__);
+       gpio_direction_output(TX48_ETH_PHY_RST_GPIO, 0);
+       udelay(100);
+       /* Release nRST */
+       gpio_set_value(TX48_ETH_PHY_RST_GPIO, 1);
+       /* Wait for PHY internal POR signal to deassert */
+       udelay(25000);
+ }
+ static void cpsw_control(int enabled)
+ {
+       /* nothing for now */
+       /* TODO : VTP was here before */
+ }
+ static struct cpsw_slave_data cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = 0,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+ };
+ void s_init(void)
+ {
+       /* Nothing to be done here */
+ }
+ static struct cpsw_platform_data cpsw_data = {
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
+       .mdio_div               = 0xff,
+       .channels               = 8,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = ARRAY_SIZE(cpsw_slaves),
+       .slave_data             = cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .mac_control            = (1 << 5) /* MIIEN */,
+       .control                = cpsw_control,
+       .gigabit_en             = 0,
+       .host_port_num          = 0,
+       .version                = CPSW_CTRL_VERSION_2,
+ };
+ int board_eth_init(bd_t *bis)
+ {
+       __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
+       __raw_writel(0x5D, GMII_SEL);
+       tx48_phy_init();
+       return cpsw_register(&cpsw_data);
+ }
+ #endif /* CONFIG_DRIVER_TI_CPSW */
+ #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+ int cpu_mmc_init(bd_t *bis)
+ {
+       return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1);
+ }
+ #endif
+ void tx48_disable_watchdog(void)
+ {
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+       while (readl(&wdtimer->wdtwwps) & (1 << 4))
+               ;
+       writel(0xaaaa, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) & (1 << 4))
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+ }
+ enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+ };
+ void show_activity(int arg)
+ {
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX48_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX48_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX48_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+ }
+ #ifdef CONFIG_OF_BOARD_SETUP
+ #ifdef CONFIG_FDT_FIXUP_PARTITIONS
+ #include <jffs2/jffs2.h>
+ #include <mtd_node.h>
+ static struct node_info nodes[] = {
+       { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
+       { "ti,am3352-gpmc", MTD_DEV_TYPE_NAND, },
+ };
+ #else
+ #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+ #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
+ static const char *tx48_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "ti,am3359-tscadc",
+ };
 -      if (ret)
++int ft_board_setup(void *blob, bd_t *bd)
+ {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+       ret = fdt_increase_size(blob, 4096);
 -
++      if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
++              return ret;
++      }
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+       karo_fdt_fixup_touchpanel(blob, tx48_touchpanels,
+                               ARRAY_SIZE(tx48_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usb0", "phys", "vcc-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       karo_fdt_update_fb_mode(blob, video_mode);
+       tx48_disable_watchdog();
+       if (get_cpu_rev() == 0) {
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34, "interrupts");
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34,
+                               "interrupt-parent");
+       }
++
++      return 0;
+ }
+ #endif /* CONFIG_OF_BOARD_SETUP */
diff --combined board/karo/tx51/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8f0105199d91f45efe8365c5a3de981053237a30
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,31 @@@
++if TARGET_TX51_8XX0
++
++config SYS_BOARD
++      default "tx51"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mx5"
++
++config SYS_CONFIG_NAME
++      default "tx51-8xx0"
++
++endif
++
++if TARGET_TX51_8XX1_2
++
++config SYS_BOARD
++      default "tx51"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mx5"
++
++config SYS_CONFIG_NAME
++      default "tx51-8xx1_2"
++
++endif
diff --combined board/karo/tx51/Makefile
index 0000000000000000000000000000000000000000,53c68a2bf5a55274eda235226891ee1dabf89e35..ee5627b78250fc11146aa02170460922f5f2a50c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,46 +1,7 @@@
 -# (C) Copyright 2009 DENX Software Engineering
 -# Author: John Rigby <jcrigby@gmail.com>
+ #
 -# See file CREDITS for list of people who contributed to this
 -# project.
++# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# This program is free software; you can redistribute it and/or
 -# modify it under the terms of the GNU General Public License as
 -# published by the Free Software Foundation; either version 2 of
 -# the License, or (at your option) any later version.
 -#
 -# 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 $(TOPDIR)/config.mk
 -
 -LDSCRIPT := $(BOARDDIR)/u-boot.lds
 -
 -LIB   = $(obj)lib$(BOARD).o
 -
 -COBJS := tx51.o
 -SOBJS := lowlevel_init.o
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -SOBJS := $(addprefix $(obj),$(SOBJS))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -#########################################################################
 -
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
++# SPDX-License-Identifier:    GPL-2.0+
+ #
 -#########################################################################
++obj-y                         += tx51.o lowlevel_init.o
diff --combined board/karo/tx51/tx51.c
index 0000000000000000000000000000000000000000,b94e537212b3f04a842d09741b718ecea526c48e..ec0995117ec87b8f62bd9c9b97565531cc5510ca
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1136 +1,1139 @@@
 -      { TX51_RESET_OUT_GPIO, GPIOF_OUTPUT_INIT_LOW, "RESET_OUT", },
+ /*
+  * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+  * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <lcd.h>
+ #include <netdev.h>
+ #include <mmc.h>
+ #include <fsl_esdhc.h>
+ #include <video_fb.h>
+ #include <ipu.h>
+ #include <mxcfb.h>
+ #include <linux/fb.h>
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <asm/arch/iomux-mx51.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/crm_regs.h>
+ #include <asm/arch/sys_proto.h>
+ #include "../common/karo.h"
+ #define TX51_FEC_RST_GPIO     IMX_GPIO_NR(2, 14)
+ #define TX51_FEC_PWR_GPIO     IMX_GPIO_NR(1, 3)
+ #define TX51_FEC_INT_GPIO     IMX_GPIO_NR(3, 18)
+ #define TX51_LED_GPIO         IMX_GPIO_NR(4, 10)
+ #define TX51_LCD_PWR_GPIO     IMX_GPIO_NR(4, 14)
+ #define TX51_LCD_RST_GPIO     IMX_GPIO_NR(4, 13)
+ #define TX51_LCD_BACKLIGHT_GPIO       IMX_GPIO_NR(1, 2)
+ #define TX51_RESET_OUT_GPIO   IMX_GPIO_NR(2, 15)
+ DECLARE_GLOBAL_DATA_PTR;
+ #define IOMUX_SION            IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0)
+ #define FEC_PAD_CTRL          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                                       PAD_CTL_SRE_FAST)
+ #define FEC_PAD_CTRL2         MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+ #define GPIO_PAD_CTRL         MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP)
+ static iomux_v3_cfg_t tx51_pads[] = {
+       /* NAND flash pads are set up in lowlevel_init.S */
+       /* RESET_OUT */
+       MX51_PAD_EIM_A21__GPIO2_15 | GPIO_PAD_CTRL,
+       /* UART pads */
+ #if CONFIG_MXC_UART_BASE == UART1_BASE
+       MX51_PAD_UART1_RXD__UART1_RXD,
+       MX51_PAD_UART1_TXD__UART1_TXD,
+       MX51_PAD_UART1_RTS__UART1_RTS,
+       MX51_PAD_UART1_CTS__UART1_CTS,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART2_BASE
+       MX51_PAD_UART2_RXD__UART2_RXD,
+       MX51_PAD_UART2_TXD__UART2_TXD,
+       MX51_PAD_EIM_D26__UART2_RTS,
+       MX51_PAD_EIM_D25__UART2_CTS,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART3_BASE
+       MX51_PAD_UART3_RXD__UART3_RXD,
+       MX51_PAD_UART3_TXD__UART3_TXD,
+       MX51_PAD_EIM_D18__UART3_RTS,
+       MX51_PAD_EIM_D17__UART3_CTS,
+ #endif
+       /* internal I2C */
+       MX51_PAD_I2C1_DAT__GPIO4_17 | IOMUX_SION,
+       MX51_PAD_I2C1_CLK__GPIO4_16 | IOMUX_SION,
+       /* FEC PHY GPIO functions */
+       MX51_PAD_GPIO1_3__GPIO1_3 | GPIO_PAD_CTRL,    /* PHY POWER */
+       MX51_PAD_EIM_A20__GPIO2_14 | GPIO_PAD_CTRL,   /* PHY RESET */
+       MX51_PAD_NANDF_CS2__GPIO3_18 | GPIO_PAD_CTRL, /* PHY INT */
+       /* FEC functions */
+       MX51_PAD_NANDF_CS3__FEC_MDC | FEC_PAD_CTRL,
+       MX51_PAD_EIM_EB2__FEC_MDIO | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_D11__FEC_RX_DV | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS4__FEC_RX_ER | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_CS7__FEC_TX_EN | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_D8__FEC_TDATA0 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS4__FEC_TDATA1 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS5__FEC_TDATA2 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS6__FEC_TDATA3 | FEC_PAD_CTRL,
+       /* strap pins for PHY configuration */
+       MX51_PAD_NANDF_RB3__GPIO3_11 | GPIO_PAD_CTRL, /* RX_CLK/REGOFF */
+       MX51_PAD_NANDF_D9__GPIO3_31 | GPIO_PAD_CTRL,  /* RXD0/Mode0 */
+       MX51_PAD_EIM_EB3__GPIO2_23 | GPIO_PAD_CTRL,   /* RXD1/Mode1 */
+       MX51_PAD_EIM_CS2__GPIO2_27 | GPIO_PAD_CTRL,   /* RXD2/Mode2 */
+       MX51_PAD_EIM_CS3__GPIO2_28 | GPIO_PAD_CTRL,   /* RXD3/nINTSEL */
+       MX51_PAD_NANDF_RB2__GPIO3_10 | GPIO_PAD_CTRL, /* COL/RMII/CRSDV */
+       MX51_PAD_EIM_CS5__GPIO2_30 | GPIO_PAD_CTRL,   /* CRS/PHYAD4 */
+       /* unusable pins on TX51 */
+       MX51_PAD_GPIO1_0__GPIO1_0,
+       MX51_PAD_GPIO1_1__GPIO1_1,
+ };
+ static const struct gpio tx51_gpios[] = {
+       /* RESET_OUT */
 -      { TX51_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC POWER", }, /* PHY POWER */
 -      { TX51_FEC_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC RESET", }, /* PHY RESET */
 -      { TX51_FEC_INT_GPIO, GPIOF_INPUT, "FEC PHY INT", },         /* PHY INT (TX_ER) */
++      { TX51_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "RESET_OUT", },
+       /* FEC PHY control GPIOs */
 -      { IMX_GPIO_NR(3, 11), GPIOF_OUTPUT_INIT_LOW, "FEC PHY REGOFF", },  /* RX_CLK/REGOFF */
 -      { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_LOW, "FEC PHY MODE0", },   /* RXD0/Mode0 */
 -      { IMX_GPIO_NR(2, 23), GPIOF_OUTPUT_INIT_LOW, "FEC PHY MODE1", },   /* RXD1/Mode1 */
 -      { IMX_GPIO_NR(2, 27), GPIOF_OUTPUT_INIT_LOW, "FEC PHY MODE2", },   /* RXD2/Mode2 */
 -      { IMX_GPIO_NR(2, 28), GPIOF_OUTPUT_INIT_LOW, "FEC PHY nINTSEL", }, /* RXD3/nINTSEL */
 -      { IMX_GPIO_NR(3, 10), GPIOF_OUTPUT_INIT_LOW, "FEC PHY RMII", },    /* COL/RMII/CRSDV */
 -      { IMX_GPIO_NR(2, 30), GPIOF_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", },  /* CRS/PHYAD4 */
++      { TX51_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC POWER", }, /* PHY POWER */
++      { TX51_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC RESET", }, /* PHY RESET */
++      { TX51_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },      /* PHY INT (TX_ER) */
+       /* FEC PHY strap pins */
 -      { IMX_GPIO_NR(4, 17), GPIOF_INPUT, "I2C1 SDA", },
 -      { IMX_GPIO_NR(4, 16), GPIOF_INPUT, "I2C1 SCL", },
++      { IMX_GPIO_NR(3, 11), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY REGOFF", },  /* RX_CLK/REGOFF */
++      { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE0", },   /* RXD0/Mode0 */
++      { IMX_GPIO_NR(2, 23), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE1", },   /* RXD1/Mode1 */
++      { IMX_GPIO_NR(2, 27), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE2", },   /* RXD2/Mode2 */
++      { IMX_GPIO_NR(2, 28), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY nINTSEL", }, /* RXD3/nINTSEL */
++      { IMX_GPIO_NR(3, 10), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RMII", },         /* COL/RMII/CRSDV */
++      { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", },  /* CRS/PHYAD4 */
+       /* module internal I2C bus */
 -      { IMX_GPIO_NR(1, 0), GPIOF_OUTPUT_INIT_LOW, "N/C", },
 -      { IMX_GPIO_NR(1, 1), GPIOF_OUTPUT_INIT_LOW, "N/C", },
++      { IMX_GPIO_NR(4, 17), GPIOFLAG_INPUT, "I2C1 SDA", },
++      { IMX_GPIO_NR(4, 16), GPIOFLAG_INPUT, "I2C1 SCL", },
+       /* Unconnected pins */
 -                              GPIOF_INPUT, "MMC CD");
++      { IMX_GPIO_NR(1, 0), GPIOFLAG_OUTPUT_INIT_LOW, "N/C", },
++      { IMX_GPIO_NR(1, 1), GPIOFLAG_OUTPUT_INIT_LOW, "N/C", },
+ };
+ /*
+  * Functions
+  */
+ /* placed in section '.data' to prevent overwriting relocation info
+  * overlayed with bss
+  */
+ static u32 wrsr __attribute__((section(".data")));
+ #define WRSR_POR      (1 << 4)
+ #define WRSR_TOUT     (1 << 1)
+ #define WRSR_SFTW     (1 << 0)
+ static void print_reset_cause(void)
+ {
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+       printf("Reset cause: ");
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+       printf("\n");
+ }
+ static void tx51_print_cpuinfo(void)
+ {
+       u32 cpurev;
+       cpurev = get_cpu_rev();
+       printf("CPU:   Freescale i.MX51 rev%d.%d at %d MHz\n",
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       print_reset_cause();
+ }
+ int board_early_init_f(void)
+ {
+       struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+       gpio_request_array(tx51_gpios, ARRAY_SIZE(tx51_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx51_pads, ARRAY_SIZE(tx51_pads));
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x04);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x50);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x04);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
+       writel(0xffcfffff, &ccm_regs->CCGR0);
+       writel(0x003fffff, &ccm_regs->CCGR1);
+       writel(0x030c003c, &ccm_regs->CCGR2);
+       writel(0x000000ff, &ccm_regs->CCGR3);
+       writel(0x00000000, &ccm_regs->CCGR4);
+       writel(0x003fc003, &ccm_regs->CCGR5);
+       writel(0x00000000, &ccm_regs->CCGR6);
+       writel(0x00000000, &ccm_regs->cmeor);
+ #ifdef CONFIG_CMD_BOOTCE
+       /* WinCE fails to enable these clocks */
+       writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
+       writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
+       writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
+ #endif
+       return 0;
+ }
+ int board_init(void)
+ {
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+               return 1;
+       }
+       return 0;
+ }
+ int dram_init(void)
+ {
+       int ret;
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               PHYS_SDRAM_1_SIZE);
+       ret = mxc_set_clock(CONFIG_SYS_MX5_HCLK,
+               CONFIG_SYS_SDRAM_CLK, MXC_DDR_CLK);
+       if (ret)
+               printf("%s: Failed to set DDR clock to %u MHz: %d\n", __func__,
+                       CONFIG_SYS_SDRAM_CLK, ret);
+       else
+               debug("%s: DDR clock set to %u.%03u MHz (desig.: %u.000 MHz)\n",
+                       __func__, mxc_get_clock(MXC_DDR_CLK) / 1000000,
+                       mxc_get_clock(MXC_DDR_CLK) / 1000 % 1000,
+                       CONFIG_SYS_SDRAM_CLK);
+       return ret;
+ }
+ void dram_init_banksize(void)
+ {
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
+                       PHYS_SDRAM_1_SIZE);
+ #if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
+                       PHYS_SDRAM_2_SIZE);
+ #endif
+ }
+ #ifdef        CONFIG_CMD_MMC
+ static const iomux_v3_cfg_t mmc0_pads[] = {
+       MX51_PAD_SD1_CMD__SD1_CMD,
+       MX51_PAD_SD1_CLK__SD1_CLK,
+       MX51_PAD_SD1_DATA0__SD1_DATA0,
+       MX51_PAD_SD1_DATA1__SD1_DATA1,
+       MX51_PAD_SD1_DATA2__SD1_DATA2,
+       MX51_PAD_SD1_DATA3__SD1_DATA3,
+       /* SD1 CD */
+       MX51_PAD_DISPB2_SER_RS__GPIO3_8 | GPIO_PAD_CTRL,
+ };
+ static const iomux_v3_cfg_t mmc1_pads[] = {
+       MX51_PAD_SD2_CMD__SD2_CMD,
+       MX51_PAD_SD2_CLK__SD2_CLK,
+       MX51_PAD_SD2_DATA0__SD2_DATA0,
+       MX51_PAD_SD2_DATA1__SD2_DATA1,
+       MX51_PAD_SD2_DATA2__SD2_DATA2,
+       MX51_PAD_SD2_DATA3__SD2_DATA3,
+       /* SD2 CD */
+       MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | GPIO_PAD_CTRL,
+ };
+ static struct tx51_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+ } tx51_esdhc_cfg[] = {
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 8),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 6),
+       },
+ };
+ static inline struct tx51_esdhc_cfg *to_tx51_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+ {
+       return container_of(cfg, struct tx51_esdhc_cfg, cfg);
+ }
+ int board_mmc_getcd(struct mmc *mmc)
+ {
+       struct tx51_esdhc_cfg *cfg = to_tx51_esdhc_cfg(mmc->priv);
+       if (cfg->cd_gpio < 0)
+               return cfg->cd_gpio;
+       debug("SD card %d is %spresent\n",
+               cfg - tx51_esdhc_cfg,
+               gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
+       return !gpio_get_value(cfg->cd_gpio);
+ }
+ int board_mmc_init(bd_t *bis)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(tx51_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx51_esdhc_cfg *cfg = &tx51_esdhc_cfg[i];
+               int ret;
+               imx_iomux_v3_setup_multiple_pads(cfg->pads,
+                                               cfg->num_pads);
+               cfg->cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+               ret = gpio_request_one(cfg->cd_gpio,
 -      { TX51_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_HIGH, "FEC PHY POWER", },
 -      { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_HIGH, "FEC PHY Mode0", },       /* RXD0/Mode0 */
 -      { IMX_GPIO_NR(2, 23), GPIOF_OUTPUT_INIT_HIGH, "FEC PHY Mode1", },       /* RXD1/Mode1 */
 -      { IMX_GPIO_NR(2, 27), GPIOF_OUTPUT_INIT_HIGH, "FEC PHY Mode2", },       /* RXD2/Mode2 */
 -      { IMX_GPIO_NR(2, 28), GPIOF_OUTPUT_INIT_HIGH, "FEC PHY nINTSEL", },     /* RXD3/nINTSEL */
++                              GPIOFLAG_INPUT, "MMC CD");
+               if (ret) {
+                       printf("Error %d requesting GPIO%d_%d\n",
+                               ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                       continue;
+               }
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc) > 0)
+                       mmc_init(mmc);
+       }
+       return 0;
+ }
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_FEC_MXC
+ #ifndef ETH_ALEN
+ #define ETH_ALEN 6
+ #endif
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+ {
+       int i;
+       struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+       struct fuse_bank *bank = &iim->bank[1];
+       struct fuse_bank1_regs *fuse = (struct fuse_bank1_regs *)bank->fuse_regs;
+       if (dev_id > 0)
+               return;
+       for (i = 0; i < ETH_ALEN; i++)
+               mac[ETH_ALEN - i - 1] = readl(&fuse->mac_addr[i]);
+ }
+ static iomux_v3_cfg_t tx51_fec_pads[] = {
+       /* reconfigure strap pins for FEC function */
+       MX51_PAD_NANDF_RB3__FEC_RX_CLK | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_D9__FEC_RDATA0 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_EB3__FEC_RDATA1 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS2__FEC_RDATA2 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS3__FEC_RDATA3 | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_RB2__FEC_COL | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS5__FEC_CRS | FEC_PAD_CTRL,
+ };
+ /* take bit 4 of PHY address from configured PHY address or
+  * set it to 0 if PHYADDR is -1 (probe for PHY)
+  */
+ #define PHYAD4 ((CONFIG_FEC_MXC_PHYADDR >> 4) & !(CONFIG_FEC_MXC_PHYADDR >> 5))
+ static struct gpio tx51_fec_gpios[] = {
 -      { IMX_GPIO_NR(2, 30), GPIOF_OUTPUT_INIT_HIGH, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
++      { TX51_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY POWER", },
++      { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode0", },    /* RXD0/Mode0 */
++      { IMX_GPIO_NR(2, 23), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode1", },    /* RXD1/Mode1 */
++      { IMX_GPIO_NR(2, 27), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode2", },    /* RXD2/Mode2 */
++      { IMX_GPIO_NR(2, 28), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY nINTSEL", },  /* RXD3/nINTSEL */
+ #if PHYAD4
 -      { IMX_GPIO_NR(2, 30), GPIOF_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
++      { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
+ #else
 -      { TX51_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
++      { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
+ #endif
+ };
+ int board_eth_init(bd_t *bis)
+ {
+       int ret;
+       /* Power up the external phy and assert strap options */
+       gpio_request_array(tx51_fec_gpios, ARRAY_SIZE(tx51_fec_gpios));
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX51_FEC_RST_GPIO, 1);
+       /* Without this delay the PHY won't work, though nothing in
+        * the datasheets suggests that it should be necessary!
+        */
+       udelay(400);
+       imx_iomux_v3_setup_multiple_pads(tx51_fec_pads,
+                                       ARRAY_SIZE(tx51_fec_pads));
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+       return ret;
+ }
+ #endif /* CONFIG_FEC_MXC */
+ enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+ };
+ void show_activity(int arg)
+ {
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX51_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX51_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX51_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+ }
+ static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX51_PAD_CSI2_D13__GPIO4_10 | GPIO_PAD_CTRL,
+       /* USB PHY reset */
+       MX51_PAD_GPIO1_4__GPIO1_4 | GPIO_PAD_CTRL,
+       /* USBOTG OC */
+       MX51_PAD_GPIO1_6__GPIO1_6 | GPIO_PAD_CTRL,
+       /* USB PHY clock enable */
+       MX51_PAD_GPIO1_7__GPIO1_7 | GPIO_PAD_CTRL,
+       /* USBH1 VBUS enable */
+       MX51_PAD_GPIO1_8__GPIO1_8 | GPIO_PAD_CTRL,
+       /* USBH1 OC */
+       MX51_PAD_GPIO1_9__GPIO1_9 | GPIO_PAD_CTRL,
+ };
+ static const struct gpio stk5_gpios[] = {
 -      { IMX_GPIO_NR(1, 4), GPIOF_OUTPUT_INIT_LOW, "ULPI PHY clk enable", },
 -      { IMX_GPIO_NR(1, 6), GPIOF_INPUT, "USBOTG OC", },
 -      { IMX_GPIO_NR(1, 7), GPIOF_OUTPUT_INIT_LOW, "ULPI PHY reset", },
 -      { IMX_GPIO_NR(1, 8), GPIOF_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
 -      { IMX_GPIO_NR(1, 9), GPIOF_INPUT, "USBH1 OC", },
++      { TX51_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
 -      .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
++      { IMX_GPIO_NR(1, 4), GPIOFLAG_OUTPUT_INIT_LOW, "ULPI PHY clk enable", },
++      { IMX_GPIO_NR(1, 6), GPIOFLAG_INPUT, "USBOTG OC", },
++      { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "ULPI PHY reset", },
++      { IMX_GPIO_NR(1, 8), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
++      { IMX_GPIO_NR(1, 9), GPIOFLAG_INPUT, "USBH1 OC", },
+ };
+ #ifdef CONFIG_LCD
+ static u16 tx51_cmap[256];
+ vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
 -      { TX51_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
 -      { TX51_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
 -      { TX51_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
++      .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx51_cmap,
+ };
+ static struct fb_videomode tx51_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ };
+ static int lcd_enabled = 1;
+ static int lcd_bl_polarity;
+ static int lcd_backlight_polarity(void)
+ {
+       return lcd_bl_polarity;
+ }
+ void lcd_enable(void)
+ {
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+               debug("Switching LCD on\n");
+               gpio_set_value(TX51_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX51_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX51_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+ }
+ void lcd_disable(void)
+ {
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+ }
+ void lcd_panel_disable(void)
+ {
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX51_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX51_LCD_RST_GPIO, 0);
+               gpio_set_value(TX51_LCD_PWR_GPIO, 0);
+       }
+ }
+ static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX51_PAD_CSI2_VSYNC__GPIO4_13,
+       /* LCD POWER_ENABLE */
+       MX51_PAD_CSI2_HSYNC__GPIO4_14,
+       /* LCD Backlight (PWM) */
+       MX51_PAD_GPIO1_2__GPIO1_2,
+       /* Display */
+       MX51_PAD_DISP1_DAT0__DISP1_DAT0,
+       MX51_PAD_DISP1_DAT1__DISP1_DAT1,
+       MX51_PAD_DISP1_DAT2__DISP1_DAT2,
+       MX51_PAD_DISP1_DAT3__DISP1_DAT3,
+       MX51_PAD_DISP1_DAT4__DISP1_DAT4,
+       MX51_PAD_DISP1_DAT5__DISP1_DAT5,
+       MX51_PAD_DISP1_DAT6__DISP1_DAT6,
+       MX51_PAD_DISP1_DAT7__DISP1_DAT7,
+       MX51_PAD_DISP1_DAT8__DISP1_DAT8,
+       MX51_PAD_DISP1_DAT9__DISP1_DAT9,
+       MX51_PAD_DISP1_DAT10__DISP1_DAT10,
+       MX51_PAD_DISP1_DAT11__DISP1_DAT11,
+       MX51_PAD_DISP1_DAT12__DISP1_DAT12,
+       MX51_PAD_DISP1_DAT13__DISP1_DAT13,
+       MX51_PAD_DISP1_DAT14__DISP1_DAT14,
+       MX51_PAD_DISP1_DAT15__DISP1_DAT15,
+       MX51_PAD_DISP1_DAT16__DISP1_DAT16,
+       MX51_PAD_DISP1_DAT17__DISP1_DAT17,
+       MX51_PAD_DISP1_DAT18__DISP1_DAT18,
+       MX51_PAD_DISP1_DAT19__DISP1_DAT19,
+       MX51_PAD_DISP1_DAT20__DISP1_DAT20,
+       MX51_PAD_DISP1_DAT21__DISP1_DAT21,
+       MX51_PAD_DISP1_DAT22__DISP1_DAT22,
+       MX51_PAD_DISP1_DAT23__DISP1_DAT23,
+       MX51_PAD_DI1_PIN2__DI1_PIN2, /* HSYNC */
+       MX51_PAD_DI1_PIN3__DI1_PIN3, /* VSYNC */
+ };
+ static const struct gpio stk5_lcd_gpios[] = {
 -              panel_info.vl_bpix = LCD_COLOR24;
++      { TX51_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
++      { TX51_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
++      { TX51_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ void lcd_ctrl_init(void *lcdbase)
+ {
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx51_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       ipu_di_clk_parent_t di_clk_parent = DI_PCLK_PLL3;
+       unsigned long di_clk_rate = 65000000;
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 8:
+                                       case 16:
+                                       case 24:
+                                       case 32:
+                                               color_depth = val;
+                                               break;
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx51_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
 -void ft_board_setup(void *blob, bd_t *bd)
++              panel_info.vl_bpix = LCD_COLOR32;
+       }
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000,
+               PICOS2KHZ(p->pixclock) % 1000);
+       if (p != &fb_mode) {
+               int ret;
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = IPU_PIX_FMT_RGB24;
+               break;
+       case 18:
+               pix_fmt = IPU_PIX_FMT_RGB666;
+               break;
+       case 16:
+               pix_fmt = IPU_PIX_FMT_RGB565;
+               break;
+       default:
+               lcd_enabled = 0;
+               printf("Invalid LCD bus width: %d\n", lcd_bus_width);
+               return;
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+               struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
+               u32 ccgr4 = readl(&ccm_regs->CCGR4);
+               /* MIPI HSC clock is required for initialization */
+               writel(ccgr4 | (3 << 12), &ccm_regs->CCGR4);
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3DEX;
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               writel(ccgr4 & ~(3 << 12), &ccm_regs->CCGR4);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+ }
+ #else
+ #define lcd_enabled 0
+ #endif /* CONFIG_LCD */
+ static void stk5_board_init(void)
+ {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+ }
+ static void stk5v3_board_init(void)
+ {
+       stk5_board_init();
+ }
+ static void tx51_set_cpu_clock(void)
+ {
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       if (had_ctrlc() || (wrsr & WRSR_TOUT))
+               return;
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+       if (mxc_set_clock(CONFIG_SYS_MX5_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+ }
+ static void tx51_init_mac(void)
+ {
+       u8 mac[ETH_ALEN];
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+       printf("MAC addr from fuse: %pM\n", mac);
+       eth_setenv_enetaddr("ethaddr", mac);
+ }
+ int board_late_init(void)
+ {
+       int ret = 0;
+       const char *baseboard;
+       env_cleanup();
+       tx51_set_cpu_clock();
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+       printf("Baseboard: %s\n", baseboard);
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       printf("ERROR: Baseboard '%s' incompatible with TX51 module!\n",
+                               baseboard);
+                       stk5v3_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+ exit:
+       tx51_init_mac();
+       gpio_set_value(TX51_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+ }
+ int checkboard(void)
+ {
+       tx51_print_cpuinfo();
+ #if CONFIG_NR_DRAM_BANKS > 1
+       printf("Board: Ka-Ro TX51-8xx1 | TX51-8xx2\n");
+ #else
+       printf("Board: Ka-Ro TX51-8xx0\n");
+ #endif
+       return 0;
+ }
+ #if defined(CONFIG_OF_BOARD_SETUP)
+ #ifdef CONFIG_FDT_FIXUP_PARTITIONS
+ #include <jffs2/jffs2.h>
+ #include <mtd_node.h>
+ static struct node_info nodes[] = {
+       { "fsl,imx51-nand", MTD_DEV_TYPE_NAND, },
+ };
+ #else
+ #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+ #endif
+ static const char *tx51_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+ };
 -      if (ret)
++int ft_board_setup(void *blob, bd_t *bd)
+ {
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+       ret = fdt_increase_size(blob, 4096);
 -
++      if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
++              return ret;
++      }
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+       karo_fdt_fixup_touchpanel(blob, tx51_touchpanels,
+                               ARRAY_SIZE(tx51_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_update_fb_mode(blob, video_mode);
++
++      return 0;
+ }
+ #endif /* CONFIG_OF_BOARD_SETUP */
diff --combined board/karo/tx53/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3e6670f5f3b146a817d66be6784196774fda782f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,99 @@@
++if TARGET_TX53
++
++config SYS_BOARD
++      default "tx53"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mx5"
++
++config SYS_CONFIG_NAME
++      default "tx53"
++
++config CMD_ROMUPDATE
++      bool
++
++config MX5
++      bool
++
++config MX53
++      bool
++      default y
++      select CPU_V7
++      select MX5
++
++config TX53
++      bool
++      default y
++      select CC_OPTIMIZE_LIBS_FOR_SPEED
++      select CMD_BMP if LCD
++      select CMD_BOOTCE
++      select CMD_BOOTZ
++      select CMD_CACHE
++      select CMD_I2C if I2C
++      select CMD_MEMINFO
++      select CMD_MEMTEST
++      select CMD_NAND
++      select CMD_NAND_TRIMFFS
++      select CMD_ROMUPDATE
++      select CMD_TIME
++      select DM
++      select DM_GPIO
++      select FDT_FIXUP_PARTITIONS if OF_LIBFDT
++      select GET_FEC_MAC_ADDR_FROM_IIM
++      select IMX_WATCHDOG
++      select MTD_PARTITIONS
++      select MTD_DEVICE
++      select MX53
++      select NAND
++      select NAND_MXC
++      select OF_LIBFDT
++      select OF_BOARD_SETUP
++      select PHYLIB
++      select PHY_SMSC
++      select SYS_I2C
++      select SYS_I2C_MXC
++      select SYS_NAND_USE_FLASH_BBT if NAND_MXC
++
++#
++# variables selected depending on module variant
++#
++
++config SYS_LVDS_IF
++      bool
++
++config NR_DRAM_BANKS
++      int
++      default 1
++
++choice
++      prompt "TX53 module variant"
++
++config TARGET_TX53_X030
++      bool "TX53-8030 and TX53-1030"
++
++config TARGET_TX53_X130
++      bool "TX53-8030 and TX53-1030"
++
++config TARGET_TX53_X131
++      bool "TX53-8131 and TX53-1131"
++
++config TARGET_TX53_1232
++      bool "TX53-1232
++
++endchoice
++
++choice
++      prompt "U-Boot image variant"
++
++config TX53_UBOOT
++      bool "Standard U-Boot image"
++
++config TX53_UBOOT_NOENV
++      bool "U-Boot using only built-in environment"
++
++endchoice
++
++endif
diff --combined board/karo/tx53/Makefile
index 0000000000000000000000000000000000000000,9ac5e7ca9cb81d55e1913f64df81e6835af9f510..7500ab63be3c2686c8f5d811bd46460b4968a56b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,42 +1,10 @@@
 -# (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# See file CREDITS for list of people who contributed to this
 -# project.
++# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
 -# 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.
 -#
 -
 -include $(TOPDIR)/config.mk
++# SPDX-License-Identifier:    GPL-2.0+
+ #
 -LIB   = $(obj)lib$(BOARD).o
 -
 -COBJS := tx53.o
 -ifeq ($(CONFIG_CMD_ROMUPDATE),y)
 -      COBJS += flash.o
 -endif
 -SOBJS := lowlevel_init.o
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -SOBJS := $(addprefix $(obj),$(SOBJS))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -#########################################################################
 -
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
+ LDSCRIPT := $(BOARDDIR)/u-boot.lds
++obj-y                         += lowlevel_init.o tx53.o
++obj-$(CONFIG_CMD_ROMUPDATE)   += flash.o
diff --combined board/karo/tx53/flash.c
index 0000000000000000000000000000000000000000,d111633e90228fddcf78502759b515146ed27146..d6463cf1057c300f59c430fd91bdf59b866227a7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,564 +1,565 @@@
 -              ret = chip->write_page(mtd, chip, buf, 1, page, 0, 1);
+ /*
+  * Copyright (C) 2011-2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <malloc.h>
+ #include <nand.h>
+ #include <errno.h>
+ #include <linux/err.h>
+ #include <jffs2/load_kernel.h>
+ struct mx53_fcb {
+       u32 rsrvd0;
+       u32 fingerprint;
+       u32 version;
+       u32 rsrvd1[23];
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 rsrvd2[2];
+       u32 dbbt_search_area;
+       u32 bb_mark_phys_offset;
+       u32 rsrvd3[11];
+       u32 bb_swap;
+       u32 bb_mark_byte;
+       u32 rsrvd4[83];
+ };
+ static nand_info_t *mtd = &nand_info[0];
+ static bool doit;
+ static inline int calc_bb_offset(struct mx53_fcb *fcb)
+ {
+       int ecc_block_size = 512;
+       int ecc_size = mtd->oobsize / (mtd->writesize / ecc_block_size);
+       int bb_mark_chunk, bb_mark_chunk_offs;
+       bb_mark_chunk = mtd->writesize / (ecc_block_size + ecc_size);
+       bb_mark_chunk_offs = mtd->writesize % (ecc_block_size + ecc_size);
+       if (bb_mark_chunk_offs > ecc_block_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       printf("BB mark is in block %d offset %d\n",
+               bb_mark_chunk, bb_mark_chunk_offs);
+       return bb_mark_chunk * ecc_block_size + bb_mark_chunk_offs;
+ }
+ /*
+  * return number of blocks to skip for a contiguous partition
+  * of given # blocks
+  */
+ static int find_contig_space(int block, int num_blocks, int max_blocks)
+ {
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+ }
+ #define offset_of(p, m)               ((void *)&(p)->m - (void *)(p))
+ #define pr_fcb_val(p, n)      debug("%-24s[%02x]=%08x(%d)\n", #n, offset_of(p, n), (p)->n, (p)->n)
+ static struct mx53_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+ {
+       struct mx53_fcb *fcb;
+       u32 sectors_per_block = mtd->erasesize / mtd->writesize;
+       fcb = buf;
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - sizeof(*fcb));
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = 1;
+       fcb->fw1_start_page = fw1_start_block * sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * sectors_per_block;
+               pr_fcb_val(fcb, fw2_start_page);
+       }
+       return fcb;
+ }
+ static int find_fcb(void *ref, int page)
+ {
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+ out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+ }
+ static int write_fcb(void *buf, int block)
+ {
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+       printf("Erasing FCB block %08x..%08x\n", block * mtd->erasesize,
+               block * mtd->erasesize + mtd->erasesize - 1);
+       if (doit) {
+               ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+               if (ret) {
+                       printf("Failed to erase FCB block %u\n", block);
+                       return ret;
+               }
+       }
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       if (doit) {
+               chip->select_chip(mtd, 0);
++              ret = chip->write_page(mtd, chip, 0, mtd->writesize,
++                              buf, 1, page, 0, 0);
+               if (ret) {
+                       printf("Failed to write FCB to block %u: %d\n", block, ret);
+               }
+               chip->select_chip(mtd, -1);
+       }
+       return ret;
+ }
+ #define chk_overlap(a,b)                              \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+ #define fail_if_overlap(a,b,m1,m2) do {                                       \
+       if (!doit)                                                      \
+               printf("check: %s[%lu..%lu] <> %s[%lu..%lu]\n",         \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+       if (a##_end_block < a##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m1);       \
+       if (b##_end_block < b##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m2);       \
+       if (chk_overlap(a, b)) {                                        \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+               return -EINVAL;                                         \
+       }                                                               \
+ } while (0)
+ static int tx53_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+ {
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = start_block * mtd->erasesize;
+       erase_opts.offset = (start_block - skip) * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       if (doit) {
+               ret = nand_erase_opts(mtd, &erase_opts);
+               if (ret) {
+                       printf("Failed to erase flash: %d\n", ret);
+                       return ret;
+               }
+       }
+       printf("Programming flash @ %08x..%08x from %p\n",
+               prg_start, prg_start + size - 1, addr);
+       if (doit) {
+               actual = size;
+               ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                                       prg_length, addr, WITH_DROP_FFS);
+               if (ret) {
+                       printf("Failed to program flash: %d\n", ret);
+                       return ret;
+               }
+               if (actual < size) {
+                       printf("Could only write %u of %u bytes\n", actual, size);
+                       return -EIO;
+               }
+       }
+       return 0;
+ }
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #ifndef CONFIG_ENV_OFFSET_REDUND
+ #define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+ #else
+ #define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+ #endif
+ #endif
+ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx53_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+ #endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+       doit = true;
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-n") == 0) {
+                       doit = false;
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               if (uboot_part) {
+                       printf("WARNING: Image size not specified; overwriting whole '%s' partition\n",
+                               uboot_part);
+                       printf("This will only work, if there are no bad blocks inside this partition!\n");
+               } else {
+                       printf("ERROR: Image size must be specified\n");
+                       return -EINVAL;
+               }
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0)
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       else
+               fw_num_blocks = 0;
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+               /*
+                * Skip one block, if the U-Boot image resides in the
+                * same partition as the FCB
+                */
+               if (fw1_start_block == fcb_start_block) {
+                       fw1_start_block++;
+                       max_len1 -= mtd->erasesize;
+               }
+               if (size == 0)
+                       fw_num_blocks = max_len1 / mtd->erasesize;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+               if (fw2_start_block == fcb_start_block) {
+                       fw2_start_block++;
+                       max_len2 -= mtd->erasesize;
+               }
+               if (size == 0)
+                       fw_num_blocks = max_len2 / mtd->erasesize;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+                       fw_num_blocks, fw1_start_block,
+                       fw1_start_block + max_len1 / mtd->erasesize - 1);
+               if (uboot_part) {
+ #ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+ #else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+ #endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       if (extra_blocks)
+               fw1_end_block = fw1_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw1_end_block = fw1_start_block + fw_num_blocks + fw1_skip - 1;
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                               fw_num_blocks, fw2_start_block,
+                               fw2_start_block + max_len2 / mtd->erasesize - 1);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       if (extra_blocks)
+               fw2_end_block = fw2_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw2_end_block = fw2_start_block + fw_num_blocks + fw2_skip - 1;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+ #endif
+       fail_if_overlap(fw1, fcb, "FW1", "FCB");
+       if (fw2_set) {
+               fail_if_overlap(fw2, fcb, "FW2", "FCB");
+ #ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+ #endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+       fw1_start_block += fw1_skip;
+       fw2_start_block += fw2_skip;
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+       fcb = create_fcb(buf, fw1_start_block,
+                       fw2_start_block, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block, (u64)fw1_start_block * mtd->erasesize);
+       ret = tx53_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+       if (ret || fw2_start_block == 0)
+               return ret;
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block, (u64)fw2_start_block * mtd->erasesize);
+       ret = tx53_prog_uboot(addr, fw2_start_block, fw2_skip, size,
+                       max_len2);
+       return ret;
+ }
+ U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\t\twrite bootloader image at block # (decimal)\n"
+       "\t-r\t\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\t\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\t\tspecify number of redundant blocks per boot loader image\n"
+       "\t\t\t(only valid if -f or -r specify a flash address rather than a partition name)\n"
+       "\t-n\t\tshow what would be done without actually updating the flash\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr})\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize})"
+       );
diff --combined board/karo/tx53/tx53.c
index 0000000000000000000000000000000000000000,9df8126ad4ded00751ad26b2c6273b5fae393e4b..26caf9d6e1a58199d6ed723c5b554a6a3df1db4d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1449 +1,1452 @@@
 -      { TX53_RESET_OUT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "#RESET_OUT", },
 -      { TX53_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
 -      { TX53_FEC_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC PHY RESET", },
 -      { TX53_FEC_INT_GPIO, GPIOF_INPUT, "FEC PHY INT", },
+ /*
+  * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+  * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <i2c.h>
+ #include <lcd.h>
+ #include <netdev.h>
+ #include <mmc.h>
+ #include <fsl_esdhc.h>
+ #include <video_fb.h>
+ #include <ipu.h>
+ #include <mxcfb.h>
+ #include <linux/fb.h>
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <asm/arch/iomux-mx53.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/crm_regs.h>
+ #include <asm/arch/sys_proto.h>
+ #include "../common/karo.h"
+ #define TX53_FEC_RST_GPIO     IMX_GPIO_NR(7, 6)
+ #define TX53_FEC_PWR_GPIO     IMX_GPIO_NR(3, 20)
+ #define TX53_FEC_INT_GPIO     IMX_GPIO_NR(2, 4)
+ #define TX53_LED_GPIO         IMX_GPIO_NR(2, 20)
+ #define TX53_LCD_PWR_GPIO     IMX_GPIO_NR(2, 31)
+ #define TX53_LCD_RST_GPIO     IMX_GPIO_NR(3, 29)
+ #define TX53_LCD_BACKLIGHT_GPIO       IMX_GPIO_NR(1, 1)
+ #define TX53_RESET_OUT_GPIO   IMX_GPIO_NR(7, 12)
+ DECLARE_GLOBAL_DATA_PTR;
+ #define MX53_GPIO_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_PUE | \
+                               PAD_CTL_DSE_HIGH | PAD_CTL_PUS_22K_UP)
+ #define TX53_SDHC_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_HYS | PAD_CTL_DSE_HIGH |   \
+                               PAD_CTL_SRE_FAST | PAD_CTL_PUS_47K_UP)
+ char __uboot_img_end[0] __attribute__((section(".__uboot_img_end")));
+ static iomux_v3_cfg_t tx53_pads[] = {
+       /* NAND flash pads are set up in lowlevel_init.S */
+       /* UART pads */
+ #if CONFIG_MXC_UART_BASE == UART1_BASE
+       MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
+       MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
+       MX53_PAD_PATA_IORDY__UART1_RTS,
+       MX53_PAD_PATA_RESET_B__UART1_CTS,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART2_BASE
+       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+       MX53_PAD_PATA_DIOR__UART2_RTS,
+       MX53_PAD_PATA_INTRQ__UART2_CTS,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART3_BASE
+       MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+       MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+       MX53_PAD_PATA_DA_2__UART3_RTS,
+       MX53_PAD_PATA_DA_1__UART3_CTS,
+ #endif
+       /* internal I2C */
+       MX53_PAD_EIM_D28__I2C1_SDA | MX53_GPIO_PAD_CTRL,
+       MX53_PAD_EIM_D21__I2C1_SCL | MX53_GPIO_PAD_CTRL,
+       /* FEC PHY GPIO functions */
+       MX53_PAD_EIM_D20__GPIO3_20, /* PHY POWER */
+       MX53_PAD_PATA_DA_0__GPIO7_6, /* PHY RESET */
+       MX53_PAD_PATA_DATA4__GPIO2_4, /* PHY INT */
+       /* FEC functions */
+       MX53_PAD_FEC_MDC__FEC_MDC,
+       MX53_PAD_FEC_MDIO__FEC_MDIO,
+       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+       MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+       MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+       MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+       MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+       MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+       MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+       MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+ };
+ static const struct gpio tx53_gpios[] = {
 -                              GPIOF_INPUT, "MMC CD");
++      { TX53_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "#RESET_OUT", },
++      { TX53_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
++      { TX53_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RESET", },
++      { TX53_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },
+ };
+ /*
+  * Functions
+  */
+ /* placed in section '.data' to prevent overwriting relocation info
+  * overlayed with bss
+  */
+ static u32 wrsr __attribute__((section(".data")));
+ #define WRSR_POR      (1 << 4)
+ #define WRSR_TOUT     (1 << 1)
+ #define WRSR_SFTW     (1 << 0)
+ static void print_reset_cause(void)
+ {
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+       printf("Reset cause: ");
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+       printf("\n");
+ }
+ #define pr_lpgr_val(v, n, b, c) do {                                  \
+       u32 __v = ((v) >> (b)) & ((1 << (c)) - 1);                      \
+       if (__v)                                                        \
+               printf(" %s=%0*x", #n, DIV_ROUND_UP(c, 4), __v);        \
+ } while (0)
+ static inline void print_lpgr(u32 lpgr)
+ {
+       if (!lpgr)
+               return;
+       printf("LPGR=%08x:", lpgr);
+       pr_lpgr_val(lpgr, SW_ISO, 31, 1);
+       pr_lpgr_val(lpgr, SECONDARY_BOOT, 30, 1);
+       pr_lpgr_val(lpgr, BLOCK_REWRITE, 29, 1);
+       pr_lpgr_val(lpgr, WDOG_BOOT, 28, 1);
+       pr_lpgr_val(lpgr, SBMR_SHADOW, 0, 26);
+       printf("\n");
+ }
+ static void tx53_print_cpuinfo(void)
+ {
+       u32 cpurev;
+       struct srtc_regs *srtc_regs = (void *)SRTC_BASE_ADDR;
+       u32 lpgr = readl(&srtc_regs->lpgr);
+       cpurev = get_cpu_rev();
+       printf("CPU:   Freescale i.MX53 rev%d.%d at %d MHz\n",
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       print_reset_cause();
+       print_lpgr(lpgr);
+       if (lpgr & (1 << 30))
+               printf("WARNING: U-Boot started from secondary bootstrap image\n");
+       if (lpgr) {
+               struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+               u32 ccgr4 = readl(&ccm_regs->CCGR4);
+               writel(ccgr4 | MXC_CCM_CCGR4_SRTC(3), &ccm_regs->CCGR4);
+               writel(0, &srtc_regs->lpgr);
+               writel(ccgr4, &ccm_regs->CCGR4);
+       }
+ }
+ enum LTC3589_REGS {
+       LTC3589_SCR1 = 0x07,
+       LTC3589_SCR2 = 0x12,
+       LTC3589_VCCR = 0x20,
+       LTC3589_CLIRQ = 0x21,
+       LTC3589_B1DTV1 = 0x23,
+       LTC3589_B1DTV2 = 0x24,
+       LTC3589_VRRCR = 0x25,
+       LTC3589_B2DTV1 = 0x26,
+       LTC3589_B2DTV2 = 0x27,
+       LTC3589_B3DTV1 = 0x29,
+       LTC3589_B3DTV2 = 0x2a,
+       LTC3589_L2DTV1 = 0x32,
+       LTC3589_L2DTV2 = 0x33,
+ };
+ #define LTC3589_BnDTV1_PGOOD_MASK     (1 << 5)
+ #define LTC3589_BnDTV1_SLEW(n)                (((n) & 3) << 6)
+ #define LTC3589_CLK_RATE_LOW          (1 << 5)
+ #define LTC3589_SCR2_PGOOD_SHUTDWN    (1 << 7)
+ #define VDD_LDO2_VAL          mV_to_regval(vout_to_vref(1325 * 10, 2))
+ #define VDD_CORE_VAL          mV_to_regval(vout_to_vref(1100 * 10, 3))
+ #define VDD_SOC_VAL           mV_to_regval(vout_to_vref(1325 * 10, 4))
+ #define VDD_BUCK3_VAL         mV_to_regval(vout_to_vref(2500 * 10, 5))
+ #ifndef CONFIG_SYS_TX53_HWREV_2
+ /* LDO2 vref divider */
+ #define R1_2  180
+ #define R2_2  191
+ /* BUCK1 vref divider */
+ #define R1_3  150
+ #define R2_3  180
+ /* BUCK2 vref divider */
+ #define R1_4  180
+ #define R2_4  191
+ /* BUCK3 vref divider */
+ #define R1_5  270
+ #define R2_5  100
+ #else
+ /* no dividers on vref */
+ #define R1_2  0
+ #define R2_2  1
+ #define R1_3  0
+ #define R2_3  1
+ #define R1_4  0
+ #define R2_4  1
+ #define R1_5  0
+ #define R2_5  1
+ #endif
+ /* calculate voltages in 10mV */
+ #define R1(idx)                       R1_##idx
+ #define R2(idx)                       R2_##idx
+ #define vout_to_vref(vout, idx)       ((vout) * R2(idx) / (R1(idx) + R2(idx)))
+ #define vref_to_vout(vref, idx)       DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
+ #define mV_to_regval(mV)      DIV_ROUND(((((mV) < 3625) ? 3625 : (mV)) - 3625), 125)
+ #define regval_to_mV(v)               (((v) * 125 + 3625))
+ static struct pmic_regs {
+       enum LTC3589_REGS addr;
+       u8 val;
+ } ltc3589_regs[] = {
+       { LTC3589_SCR1, 0x15, }, /* burst mode for all regulators except buck boost */
+       { LTC3589_SCR2, LTC3589_SCR2_PGOOD_SHUTDWN, }, /* enable shutdown on PGOOD Timeout */
+       { LTC3589_L2DTV1, VDD_LDO2_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_L2DTV2, VDD_LDO2_VAL | LTC3589_CLK_RATE_LOW, },
+       { LTC3589_B1DTV1, VDD_CORE_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B1DTV2, VDD_CORE_VAL, },
+       { LTC3589_B2DTV1, VDD_SOC_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B2DTV2, VDD_SOC_VAL, },
+       { LTC3589_B3DTV1, VDD_BUCK3_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B3DTV2, VDD_BUCK3_VAL, },
+       /* Select ref 0 for all regulators and enable slew */
+       { LTC3589_VCCR, 0x55, },
+       { LTC3589_CLIRQ, 0, }, /* clear all interrupt flags */
+ };
+ static int setup_pmic_voltages(void)
+ {
+       int ret;
+       unsigned char value;
+       int i;
+       ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
+       if (ret != 0) {
+               printf("Failed to initialize I2C\n");
+               return ret;
+       }
+       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
+       for (i = 0; i < ARRAY_SIZE(ltc3589_regs); i++) {
+               ret = i2c_read(CONFIG_SYS_I2C_SLAVE, ltc3589_regs[i].addr, 1,
+                               &value, 1);
+               debug("Writing %02x to reg %02x (%02x)\n",
+                       ltc3589_regs[i].val, ltc3589_regs[i].addr, value);
+               ret = i2c_write(CONFIG_SYS_I2C_SLAVE, ltc3589_regs[i].addr, 1,
+                               &ltc3589_regs[i].val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, ltc3589_regs[i].addr, ret);
+                       return ret;
+               }
+       }
+       printf("VDDCORE set to %umV\n",
+               DIV_ROUND(vref_to_vout(regval_to_mV(VDD_CORE_VAL), 3), 10));
+       printf("VDDSOC  set to %umV\n",
+               DIV_ROUND(vref_to_vout(regval_to_mV(VDD_SOC_VAL), 4), 10));
+       return 0;
+ }
+ static struct {
+       u32 max_freq;
+       u32 mV;
+ } tx53_core_voltages[] = {
+       { 800000000, 1100, },
+       { 1000000000, 1240, },
+       { 1200000000, 1350, },
+ };
+ int adjust_core_voltage(u32 freq)
+ {
+       int ret;
+       int i;
+       printf("%s@%d\n", __func__, __LINE__);
+       for (i = 0; i < ARRAY_SIZE(tx53_core_voltages); i++) {
+               if (freq <= tx53_core_voltages[i].max_freq) {
+                       int retries = 0;
+                       const int max_tries = 10;
+                       const int delay_us = 1;
+                       u32 mV = tx53_core_voltages[i].mV;
+                       u8 val = mV_to_regval(vout_to_vref(mV * 10, 3));
+                       u8 v;
+                       debug("regval[%umV]=%02x\n", mV, val);
+                       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, LTC3589_B1DTV1, 1,
+                               &v, 1);
+                       if (ret) {
+                               printf("%s: failed to read PMIC register %02x: %d\n",
+                                       __func__, LTC3589_B1DTV1, ret);
+                               return ret;
+                       }
+                       debug("Changing reg %02x from %02x to %02x\n",
+                               LTC3589_B1DTV1, v, (v & ~0x1f) |
+                               mV_to_regval(vout_to_vref(mV * 10, 3)));
+                       v &= ~0x1f;
+                       v |= mV_to_regval(vout_to_vref(mV * 10, 3));
+                       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3589_B1DTV1, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to write PMIC register %02x: %d\n",
+                                       __func__, LTC3589_B1DTV1, ret);
+                               return ret;
+                       }
+                       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, LTC3589_VCCR, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to read PMIC register %02x: %d\n",
+                                       __func__, LTC3589_VCCR, ret);
+                               return ret;
+                       }
+                       v |= 0x1;
+                       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3589_VCCR, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to write PMIC register %02x: %d\n",
+                                       __func__, LTC3589_VCCR, ret);
+                               return ret;
+                       }
+                       for (retries = 0; retries < max_tries; retries++) {
+                               ret = i2c_read(CONFIG_SYS_I2C_SLAVE,
+                                       LTC3589_VCCR, 1, &v, 1);
+                               if (ret) {
+                                       printf("%s: failed to read PMIC register %02x: %d\n",
+                                               __func__, LTC3589_VCCR, ret);
+                                       return ret;
+                               }
+                               if (!(v & 1))
+                                       break;
+                               udelay(delay_us);
+                       }
+                       if (v & 1) {
+                               printf("change of VDDCORE did not complete after %uµs\n",
+                                       retries * delay_us);
+                               return -ETIMEDOUT;
+                       }
+                       printf("VDDCORE set to %umV after %u loops\n",
+                               DIV_ROUND(vref_to_vout(regval_to_mV(val & 0x1f), 3),
+                                       10), retries);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+ }
+ int board_early_init_f(void)
+ {
+       struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+       gpio_request_array(tx53_gpios, ARRAY_SIZE(tx53_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx53_pads, ARRAY_SIZE(tx53_pads));
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x04);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x50);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x04);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
+       writel(0xffcf0fff, &ccm_regs->CCGR0);
+       writel(0x000fffcf, &ccm_regs->CCGR1);
+       writel(0x033c0000, &ccm_regs->CCGR2);
+       writel(0x000000ff, &ccm_regs->CCGR3);
+       writel(0x00000000, &ccm_regs->CCGR4);
+       writel(0x00fff033, &ccm_regs->CCGR5);
+       writel(0x0f00030f, &ccm_regs->CCGR6);
+       writel(0xfff00000, &ccm_regs->CCGR7);
+       writel(0x00000000, &ccm_regs->cmeor);
+       return 0;
+ }
+ int board_init(void)
+ {
+       int ret;
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected; Skipping PMIC setup\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+               return 1;
+       }
+       ret = setup_pmic_voltages();
+       if (ret) {
+               printf("Failed to setup PMIC voltages\n");
+               hang();
+       }
+       return 0;
+ }
+ int dram_init(void)
+ {
+       int ret;
+       /*
+        * U-Boot doesn't support RAM banks with intervening holes,
+        * so let U-Boot only know about the first bank for its
+        * internal data structures. The size reported to Linux is
+        * determined from the individual bank sizes.
+        */
+       gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, SZ_1G);
+       ret = mxc_set_clock(CONFIG_SYS_MX5_HCLK,
+               CONFIG_SYS_SDRAM_CLK, MXC_DDR_CLK);
+       if (ret)
+               printf("%s: Failed to set DDR clock to %u MHz: %d\n", __func__,
+                       CONFIG_SYS_SDRAM_CLK, ret);
+       else
+               debug("%s: DDR clock set to %u.%03u MHz (desig.: %u.000 MHz)\n",
+                       __func__, mxc_get_clock(MXC_DDR_CLK) / 1000000,
+                       mxc_get_clock(MXC_DDR_CLK) / 1000 % 1000,
+                       CONFIG_SYS_SDRAM_CLK);
+       return ret;
+ }
+ void dram_init_banksize(void)
+ {
+       long total_size = gd->ram_size;
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = gd->ram_size;
+ #if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, SZ_1G);
+       if (gd->bd->bi_dram[1].size) {
+               debug("Found %luMiB SDRAM in bank 2\n",
+                       gd->bd->bi_dram[1].size / SZ_1M);
+               gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+               total_size += gd->bd->bi_dram[1].size;
+       }
+ #endif
+       if (total_size != CONFIG_SYS_SDRAM_SIZE)
+               printf("WARNING: SDRAM size mismatch: %uMiB configured; %luMiB detected\n",
+                       CONFIG_SYS_SDRAM_SIZE / SZ_1M, total_size / SZ_1M);
+ }
+ #ifdef        CONFIG_CMD_MMC
+ static const iomux_v3_cfg_t mmc0_pads[] = {
+       MX53_PAD_SD1_CMD__ESDHC1_CMD | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_CLK__ESDHC1_CLK | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA0__ESDHC1_DAT0 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA1__ESDHC1_DAT1 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA2__ESDHC1_DAT2 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA3__ESDHC1_DAT3 | TX53_SDHC_PAD_CTRL,
+       /* SD1 CD */
+       MX53_PAD_EIM_D24__GPIO3_24 | MX53_GPIO_PAD_CTRL,
+ };
+ static const iomux_v3_cfg_t mmc1_pads[] = {
+       MX53_PAD_SD2_CMD__ESDHC2_CMD | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_CLK__ESDHC2_CLK | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA0__ESDHC2_DAT0 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA1__ESDHC2_DAT1 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA2__ESDHC2_DAT2 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA3__ESDHC2_DAT3 | TX53_SDHC_PAD_CTRL,
+       /* SD2 CD */
+       MX53_PAD_EIM_D25__GPIO3_25 | MX53_GPIO_PAD_CTRL,
+ };
+ static struct tx53_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+ } tx53_esdhc_cfg[] = {
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 24),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 25),
+       },
+ };
+ static inline struct tx53_esdhc_cfg *to_tx53_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+ {
+       return container_of(cfg, struct tx53_esdhc_cfg, cfg);
+ }
+ int board_mmc_getcd(struct mmc *mmc)
+ {
+       struct tx53_esdhc_cfg *cfg = to_tx53_esdhc_cfg(mmc->priv);
+       if (cfg->cd_gpio < 0)
+               return cfg->cd_gpio;
+       debug("SD card %d is %spresent\n",
+               cfg - tx53_esdhc_cfg,
+               gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
+       return !gpio_get_value(cfg->cd_gpio);
+ }
+ int board_mmc_init(bd_t *bis)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(tx53_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx53_esdhc_cfg *cfg = &tx53_esdhc_cfg[i];
+               int ret;
+               imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads);
+               cfg->cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+               ret = gpio_request_one(cfg->cd_gpio,
 -      { TX53_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
++                              GPIOFLAG_INPUT, "MMC CD");
+               if (ret) {
+                       printf("Error %d requesting GPIO%d_%d\n",
+                               ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                       continue;
+               }
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc) > 0)
+                       mmc_init(mmc);
+       }
+       return 0;
+ }
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_FEC_MXC
+ #ifndef ETH_ALEN
+ #define ETH_ALEN 6
+ #endif
+ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+ {
+       int i;
+       struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+       struct fuse_bank *bank = &iim->bank[1];
+       struct fuse_bank1_regs *fuse = (struct fuse_bank1_regs *)bank->fuse_regs;
+       if (dev_id > 0)
+               return;
+       for (i = 0; i < ETH_ALEN; i++)
+               mac[i] = readl(&fuse->mac_addr[i]);
+ }
+ #define FEC_PAD_CTL   (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                       PAD_CTL_SRE_FAST)
+ #define FEC_PAD_CTL2  (PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+ #define GPIO_PAD_CTL  (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+ int board_eth_init(bd_t *bis)
+ {
+       int ret;
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX53_FEC_RST_GPIO, 1);
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+       return ret;
+ }
+ #endif /* CONFIG_FEC_MXC */
+ enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+ };
+ void show_activity(int arg)
+ {
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX53_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX53_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX53_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+ }
+ static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX53_PAD_EIM_A18__GPIO2_20,
+       /* I2C bus on DIMM pins 40/41 */
+       MX53_PAD_GPIO_6__I2C3_SDA | MX53_GPIO_PAD_CTRL,
+       MX53_PAD_GPIO_3__I2C3_SCL | MX53_GPIO_PAD_CTRL,
+       /* TSC200x PEN IRQ */
+       MX53_PAD_EIM_D26__GPIO3_26 | MX53_GPIO_PAD_CTRL,
+       /* EDT-FT5x06 Polytouch panel */
+       MX53_PAD_NANDF_CS2__GPIO6_15 | MX53_GPIO_PAD_CTRL, /* IRQ */
+       MX53_PAD_EIM_A16__GPIO2_22 | MX53_GPIO_PAD_CTRL, /* RESET */
+       MX53_PAD_EIM_A17__GPIO2_21 | MX53_GPIO_PAD_CTRL, /* WAKE */
+       /* USBH1 */
+       MX53_PAD_EIM_D31__GPIO3_31 | MX53_GPIO_PAD_CTRL, /* VBUSEN */
+       MX53_PAD_EIM_D30__GPIO3_30 | MX53_GPIO_PAD_CTRL, /* OC */
+       /* USBOTG */
+       MX53_PAD_GPIO_7__GPIO1_7, /* VBUSEN */
+       MX53_PAD_GPIO_8__GPIO1_8, /* OC */
+       /* DS1339 Interrupt */
+       MX53_PAD_DI0_PIN4__GPIO4_20 | MX53_GPIO_PAD_CTRL,
+ };
+ static const struct gpio stk5_gpios[] = {
 -      { IMX_GPIO_NR(1, 8), GPIOF_INPUT, "USBOTG OC", },
 -      { IMX_GPIO_NR(1, 7), GPIOF_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
 -      { IMX_GPIO_NR(3, 30), GPIOF_INPUT, "USBH1 OC", },
 -      { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
++      { TX53_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
 -      .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
++      { IMX_GPIO_NR(1, 8), GPIOFLAG_INPUT, "USBOTG OC", },
++      { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
++      { IMX_GPIO_NR(3, 30), GPIOFLAG_INPUT, "USBH1 OC", },
++      { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
+ };
+ #ifdef CONFIG_LCD
+ static u16 tx53_cmap[256];
+ vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
 -      { TX53_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
 -      { TX53_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
 -      { TX53_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
++      .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx53_cmap,
+ };
+ static struct fb_videomode tx53_fb_modes[] = {
+ #ifndef CONFIG_SYS_LVDS_IF
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ #else
+       {
+               /* HannStar HSD100PXN1
+                * 202.7m mm x 152.06 mm display area.
+                */
+               .name           = "HSD100PXN1",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = KHZ2PICOS(65000),
+               .left_margin    = 0,
+               .hsync_len      = 0,
+               .right_margin   = 320,
+               .upper_margin   = 0,
+               .vsync_len      = 0,
+               .lower_margin   = 38,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ #endif
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ };
+ static int lcd_enabled = 1;
+ static int lcd_bl_polarity;
+ static int lcd_backlight_polarity(void)
+ {
+       return lcd_bl_polarity;
+ }
+ void lcd_enable(void)
+ {
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+               debug("Switching LCD on\n");
+               gpio_set_value(TX53_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX53_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX53_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+ }
+ void lcd_disable(void)
+ {
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+ }
+ void lcd_panel_disable(void)
+ {
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX53_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX53_LCD_RST_GPIO, 0);
+               gpio_set_value(TX53_LCD_PWR_GPIO, 0);
+       }
+ }
+ static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX53_PAD_EIM_D29__GPIO3_29 | MX53_GPIO_PAD_CTRL,
+       /* LCD POWER_ENABLE */
+       MX53_PAD_EIM_EB3__GPIO2_31 | MX53_GPIO_PAD_CTRL,
+       /* LCD Backlight (PWM) */
+       MX53_PAD_GPIO_1__GPIO1_1 | MX53_GPIO_PAD_CTRL,
+       /* Display */
+ #ifndef CONFIG_SYS_LVDS_IF
+       /* LCD option */
+       MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
+       MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
+       MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
+       MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
+       MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
+       MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
+       MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
+       MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
+       MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
+       MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
+       MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
+       MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
+       MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
+       MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
+       MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
+       MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
+       MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
+       MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
+       MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
+       MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
+       MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
+       MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
+       MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
+       MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
+       MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
+       MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
+       MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
+       MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
+ #else
+       /* LVDS option */
+       MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+       MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+       MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+       MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+       MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+       MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+       MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+       MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+       MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+       MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+ #endif
+ };
+ static const struct gpio stk5_lcd_gpios[] = {
 -              panel_info.vl_bpix = LCD_COLOR24;
++      { TX53_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
++      { TX53_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
++      { TX53_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ void lcd_ctrl_init(void *lcdbase)
+ {
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx53_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       ipu_di_clk_parent_t di_clk_parent = is_lvds() ? DI_PCLK_LDB : DI_PCLK_PLL3;
+       unsigned long di_clk_rate = 65000000;
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 32:
+                                       case 24:
+                                               if (is_lvds())
+                                                       pix_fmt = IPU_PIX_FMT_LVDS888;
+                                               /* fallthru */
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+                                       case 18:
+                                               if (is_lvds()) {
+                                                       color_depth = val;
+                                                       break;
+                                               }
+                                               /* fallthru */
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx53_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
 -      gpio_request_one(IMX_GPIO_NR(4, 21), GPIOF_OUTPUT_INIT_HIGH,
++              panel_info.vl_bpix = LCD_COLOR32;
+       }
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+       if (p != &fb_mode) {
+               int ret;
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24;
+               break;
+       case 18:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666;
+               break;
+       case 16:
+               if (!is_lvds()) {
+                       pix_fmt = IPU_PIX_FMT_RGB565;
+                       break;
+               }
+               /* fallthru */
+       default:
+               lcd_enabled = 0;
+               printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD",
+                       lcd_bus_width);
+               return;
+       }
+       if (is_lvds()) {
+               int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0);
+               int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt);
+               uint32_t gpr2;
+               if (lvds_chan_mask == 0) {
+                       printf("No LVDS channel active\n");
+                       lcd_enabled = 0;
+                       return;
+               }
+               gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8);
+               if (lcd_bus_width == 24)
+                       gpr2 |= (1 << 5) | (1 << 7);
+               gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0;
+               gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0;
+               debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8);
+               writel(gpr2, IOMUXC_BASE_ADDR + 8);
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3M;
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+ }
+ #else
+ #define lcd_enabled 0
+ #endif /* CONFIG_LCD */
+ static void stk5_board_init(void)
+ {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+ }
+ static void stk5v3_board_init(void)
+ {
+       stk5_board_init();
+ }
+ static void stk5v5_board_init(void)
+ {
+       stk5_board_init();
 -void ft_board_setup(void *blob, bd_t *bd)
++      gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
+       imx_iomux_v3_setup_pad(MX53_PAD_DISP0_DAT0__GPIO4_21);
+ }
+ static void tx53_set_cpu_clock(void)
+ {
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (wrsr & WRSR_TOUT) ? "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+       if (mxc_set_clock(CONFIG_SYS_MX5_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+ }
+ static void tx53_init_mac(void)
+ {
+       u8 mac[ETH_ALEN];
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+       printf("MAC addr from fuse: %pM\n", mac);
+       eth_setenv_enetaddr("ethaddr", mac);
+ }
+ int board_late_init(void)
+ {
+       int ret = 0;
+       const char *baseboard;
+       env_cleanup();
+       tx53_set_cpu_clock();
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+       printf("Baseboard: %s\n", baseboard);
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+ exit:
+       tx53_init_mac();
+       gpio_set_value(TX53_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+ }
+ int checkboard(void)
+ {
+       tx53_print_cpuinfo();
+ #if CONFIG_SYS_SDRAM_SIZE < SZ_1G
+       printf("Board: Ka-Ro TX53-8%d3%c\n",
+               is_lvds(), '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+ #elif CONFIG_SYS_SDRAM_SIZE < SZ_2G
+       printf("Board: Ka-Ro TX53-1%d3%c\n",
+               is_lvds() + 2, '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+ #else
+       printf("Board: Ka-Ro TX53-123%c\n",
+               '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+ #endif
+       return 0;
+ }
+ #if defined(CONFIG_OF_BOARD_SETUP)
+ #ifdef CONFIG_FDT_FIXUP_PARTITIONS
+ #include <jffs2/jffs2.h>
+ #include <mtd_node.h>
+ static struct node_info nodes[] = {
+       { "fsl,imx53-nand", MTD_DEV_TYPE_NAND, },
+ };
+ #else
+ #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+ #endif
+ #ifdef CONFIG_SYS_TX53_HWREV_2
+ static void tx53_fixup_rtc(void *blob)
+ {
+       karo_fdt_del_prop(blob, "dallas,ds1339", 0x68, "interrupt-parent");
+       karo_fdt_del_prop(blob, "dallas,ds1339", 0x68, "interrupts");
+ }
+ #else
+ static inline void tx53_fixup_rtc(void *blob)
+ {
+ }
+ #endif /* CONFIG_SYS_TX53_HWREV_2 */
+ static const char *tx53_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "eeti,egalax_ts",
+ };
 -      if (ret)
++int ft_board_setup(void *blob, bd_t *bd)
+ {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+       ret = fdt_increase_size(blob, 4096);
 -
++      if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
++              return ret;
++      }
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+       karo_fdt_fixup_touchpanel(blob, tx53_touchpanels,
+                               ARRAY_SIZE(tx53_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       tx53_fixup_rtc(blob);
+       karo_fdt_update_fb_mode(blob, video_mode);
++
++      return 0;
+ }
+ #endif /* CONFIG_OF_BOARD_SETUP */
diff --combined board/karo/tx6/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c61f91afec699d3cbe47c68dded88367bc1db3c6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,169 @@@
++if TARGET_TX6
++
++config MX6
++      bool
++      default y
++
++config MX6Q
++      bool
++
++config MX6DL
++      bool
++
++config MX6QDL
++      bool
++
++config MX6S
++      bool
++
++config MX6SL
++      bool
++
++config MX6SX
++      bool
++
++config SYS_BOARD
++      default "tx6"
++
++config SYS_VENDOR
++      default "karo"
++
++config SYS_SOC
++      default "mx6"
++
++config SYS_CONFIG_NAME
++      default "tx6"
++
++config CMD_ROMUPDATE
++      bool
++
++config TX6
++      bool
++      default y
++      select MX6
++      select CMD_BMP if LCD
++      select CMD_BOOTCE
++      select CMD_BOOTZ
++      select CMD_CACHE
++      select CMD_I2C if I2C
++      select CMD_MEMTEST
++      select CMD_TIME
++      select DM
++      select DM_GPIO
++      select SYS_I2C
++      select SYS_I2C_MXC
++      select GET_FEC_MAC_ADDR_FROM_IIM
++
++config TX6_NAND
++      bool
++      default ! TX6_EMMC
++      select CMD_NAND
++      select CMD_NAND_TRIMFFS
++      select CMD_MTDPARTS
++      select CMD_ROMUPDATE
++      select FDT_FIXUP_PARTITIONS if OF_LIBFDT
++      select MTD_PARTITIONS
++      select NAND_MXS_NO_BBM_SWAP if NAND_MXS
++      select SYS_NAND_USE_FLASH_BBT if NAND_MXS
++      select APBH_DMA
++      select APBH_DMA_BURST
++      select APBH_DMA_BURST8
++      select MTD_DEVICE
++
++config TX6_EMMC
++      bool
++      select SUPPORT_EMMC_BOOT
++
++#
++# variables selected depending on module variant
++#
++config SYS_LVDS_IF
++      bool
++
++config SYS_SDRAM_BUS_WIDTH_16
++      bool
++
++config SYS_SDRAM_BUS_WIDTH_32
++      bool
++
++
++choice
++      prompt "TX6 module variant"
++
++config TARGET_TX6Q_10X0
++      bool "TX6Q-1010 and TX6Q-1030"
++      select MX6Q
++
++config TARGET_TX6Q_1020
++      bool "TX6Q-1020"
++      select MX6Q
++      select TX6_EMMC
++      select TX6_REV_2
++
++config TARGET_TX6Q_11X0
++      bool "TX6Q-1110 and TX6Q-1130"
++      select MX6Q
++      select SYS_LVDS_IF
++      
++config TARGET_TX6S_8034
++      bool "TX6S-8034"
++      select MX6S
++      select SYS_SDRAM_BUS_WIDTH_16
++
++config TARGET_TX6S_8035
++      bool "TX6S-8035"
++      select MX6S
++      select TX6_EMMC
++      select SYS_SDRAM_BUS_WIDTH_32
++
++config TARGET_TX6U_8010
++      bool "TX6U-8010 and TX6U-8030"
++      select MX6DL
++
++config TARGET_TX6U_8011
++      bool "TX6U-8011"
++      select MX6DL
++      select SYS_SDRAM_BUS_WIDTH_32
++      select TX6_REV_1
++
++config TARGET_TX6U_8012
++      bool "TX6U-8012"
++      select MX6DL
++      select TX6_REV_1
++
++config TARGET_TX6U_81X0
++      bool "TX6U-8110 and TX6U-8130"
++      select MX6DL
++      select SYS_LVDS_IF
++
++config TARGET_TX6U_8111
++      bool "TX6U-8111"
++      select MX6DL
++      select SYS_SDRAM_BUS_WIDTH_32
++      select SYS_LVDS_IF
++      select TX6_REV_1
++
++config TARGET_TX6U_8033
++      bool "TX6U-8033"
++      select MX6DL
++      select TX6_EMMC
++      select TX6_REV_3
++
++endchoice
++
++choice
++      prompt "U-Boot image variant"
++      default TX6_UBOOT
++
++config TX6_UBOOT
++      bool "Standard U-Boot image"
++
++config TX6_UBOOT_MFG
++      bool "U-Boot image for use with Freescale's MfGTool"
++
++config TX6_UBOOT_NOENV
++      bool "U-Boot using only built-in environment"
++
++endchoice
++
++endif
diff --combined board/karo/tx6/Makefile
index 0000000000000000000000000000000000000000,a353e5a6aff5bd36c2b6cc593b1bb9bea5e2fcd4..74d5c0cd18a54d1672aa7e00863e7436d8a3fa69
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,34 +1,14 @@@
 -# (C) Copyright 2009 DENX Software Engineering
 -# Author: John Rigby <jcrigby@gmail.com>
+ #
 -include $(TOPDIR)/config.mk
++# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ #
+ # SPDX-License-Identifier:    GPL-2.0+
+ #
 -LIB   = $(obj)lib$(BOARD).o
++LDSCRIPT := $(BOARDDIR)/u-boot.lds
 -COBJS-y       := tx6qdl.o
 -COBJS-$(CONFIG_LTC3676)       += ltc3676.o
 -COBJS-$(CONFIG_RN5T567)       += rn5t567.o
 -COBJS-$(CONFIG_RN5T618)       += rn5t618.o
 -
 -COBJS-$(CONFIG_CMD_ROMUPDATE) += flash.o
 -
 -SOBJS-y       := lowlevel_init.o
 -
 -SRCS  := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS-y))
 -SOBJS := $(addprefix $(obj),$(SOBJS-y))
 -
 -$(LIB):       $(obj).depend $(OBJS) $(SOBJS)
 -      $(call cmd_link_o_target, $(OBJS) $(SOBJS))
 -
 -#########################################################################
 -
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
++obj-y                         += lowlevel_init.o pmic.o tx6qdl.o
++obj-$(CONFIG_LTC3676)         += ltc3676.o
++obj-$(CONFIG_RN5T567)         += rn5t567.o
++obj-$(CONFIG_RN5T618)         += rn5t618.o
++obj-$(CONFIG_CMD_ROMUPDATE)   += flash.o
diff --combined board/karo/tx6/config.mk
index 0000000000000000000000000000000000000000,c8af7c793e1ed8495146032e806ed52cb03f53e5..c1215d5a49e623c280b622c8a59c87c9b3f99f3d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,55 +1,57 @@@
 -ifeq ($(CONFIG_NO_NAND),)
+ # stack is allocated below CONFIG_SYS_TEXT_BASE
+ CONFIG_SYS_TEXT_BASE := 0x10100000
++__HAVE_ARCH_GENERIC_BOARD := y
++
+ LOGO_BMP = logos/karo.bmp
+ #PLATFORM_CPPFLAGS += -DDEBUG
+ #PLATFORM_CPPFLAGS += -Wno-unused-but-set-variable
+ PLATFORM_CPPFLAGS += -Werror
 -endif # CONFIG_NO_NAND
++ifeq ($(CONFIG_TX6_NAND),y)
+ # calculate U_BOOT_IMG_SIZE to be at least 3 eraseblocks larger than the maximum expected image size
+ CONFIG_SYS_NAND_BLOCK_SIZE := 131072
+ ifeq ($(CONFIG_SYS_NAND_BLOCKS),)
+ CONFIG_SYS_NAND_BLOCKS := 1024
+ endif
+ ifneq ($(CONFIG_SYS_NAND_BLOCK_SIZE),)
+ CONFIG_U_BOOT_IMG_SIZE := $(shell echo 'e=$(CONFIG_SYS_NAND_BLOCK_SIZE);s=640*1024;s + (e - s % e) % e + 3*e' | bc)
+ CONFIG_SYS_USERFS_SIZE := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - 12 \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_IMG_SIZE) - 38 \* 1048576)
+ CONFIG_SYS_USERFS_SIZE2 := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - 15 \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_IMG_SIZE) - 38 \* 1048576)
+ CONFIG_SYS_NAND_BBT_BLOCKS := 4
+ CONFIG_SYS_NAND_DTB_BLOCKS := 4
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BLOCKS=$(CONFIG_SYS_NAND_BLOCKS)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BLOCK_SIZE=$(CONFIG_SYS_NAND_BLOCK_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_U_BOOT_IMG_SIZE=$(CONFIG_U_BOOT_IMG_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_U_BOOT_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_U_BOOT_IMG_SIZE) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_U_BOOT_OFFS=$(shell printf "0x%x" `expr $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_ENV_PART_SIZE=$(shell printf "%uk" `expr 3 \* $(CONFIG_SYS_NAND_BLOCK_SIZE) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE2=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_NAND_BLOCK_SIZE) \* $(CONFIG_SYS_NAND_BBT_BLOCKS) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_DTB_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_DTB_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BBT_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_NAND_BBT_BLOCKS) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) / 1024`)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BBT_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+ endif # CONFIG_SYS_NAND_BLOCK_SIZE
+ else
+ ifneq ($(CONFIG_MMC_BOOT_SIZE),)
+       CONFIG_SYS_MMC_BOOT_PART_SIZE := $(shell expr $(CONFIG_MMC_BOOT_SIZE) \* 1024)
+ else
+       CONFIG_SYS_MMC_BOOT_PART_SIZE := $(shell expr 4096 \* 1024)
+ endif
+ CONFIG_U_BOOT_IMG_SIZE := $(shell expr 1 \* 1048576)
+ CONFIG_MAX_DTB_SIZE := $(shell expr 64 \* 1024)
+ CONFIG_ENV_SIZE := $(shell expr 128 \* 1024)
+ CONFIG_ENV_OFFSET := $(shell expr $(CONFIG_SYS_MMC_BOOT_PART_SIZE) - $(CONFIG_ENV_SIZE))
+ CONFIG_SYS_DTB_OFFSET := $(shell expr $(CONFIG_ENV_OFFSET) - $(CONFIG_MAX_DTB_SIZE))
+ PLATFORM_CPPFLAGS += -DCONFIG_ENV_SIZE=$(CONFIG_ENV_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_U_BOOT_IMG_SIZE=$(CONFIG_U_BOOT_IMG_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_MAX_DTB_SIZE=$(CONFIG_MAX_DTB_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_PART_SIZE=$(CONFIG_MAX_DTB_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_MMC_BOOT_PART_SIZE=$(CONFIG_SYS_MMC_BOOT_PART_SIZE)
+ PLATFORM_CPPFLAGS += -DCONFIG_ENV_OFFSET=$(shell printf "0x%x" $(CONFIG_ENV_OFFSET))
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_OFFSET=$(shell printf "0x%x" $(CONFIG_SYS_DTB_OFFSET))
+ PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_BLKNO=$(shell printf "0x%x" `expr $(CONFIG_SYS_DTB_OFFSET) / 512`)
++endif # CONFIG_TX6_NAND
diff --combined board/karo/tx6/flash.c
index 0000000000000000000000000000000000000000,ce90c4e6c9d9caa1f5c584f93a666b8f79827c24..d0bb7c858ff677ddd6e11d25013e5b94558f6007
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,738 +1,739 @@@
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <malloc.h>
+ #include <nand.h>
+ #include <errno.h>
+ #include <linux/err.h>
+ #include <jffs2/load_kernel.h>
+ #include <asm/io.h>
 -      ret = chip->write_page(mtd, chip, buf, 1, page, 0, 1);
++#include <linux/sizes.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/imx-common/regs-gpmi.h>
+ #include <asm/imx-common/regs-bch.h>
+ struct mx6_nand_timing {
+       u8 data_setup;
+       u8 data_hold;
+       u8 address_setup;
+       u8 dsample_time;
+       u8 nand_timing_state;
+       u8 tREA;
+       u8 tRLOH;
+       u8 tRHOH;
+ };
+ struct mx6_fcb {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       struct mx6_nand_timing timing;
+       u32 page_data_size;
+       u32 total_page_size;
+       u32 sectors_per_block;
+       u32 number_of_nands;    /* not used by ROM code */
+       u32 total_internal_die; /* not used by ROM code */
+       u32 cell_type;          /* not used by ROM code */
+       u32 ecc_blockn_type;
+       u32 ecc_block0_size;
+       u32 ecc_blockn_size;
+       u32 ecc_block0_type;
+       u32 metadata_size;
+       u32 ecc_blocks_per_page;
+       u32 rsrvd1[6];          /* not used by ROM code */
+       u32 bch_mode;           /* erase_threshold */
+       u32 rsrvd2[2];
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 fw1_sectors;
+       u32 fw2_sectors;
+       u32 dbbt_search_area;
+       u32 bb_mark_byte;
+       u32 bb_mark_startbit;
+       u32 bb_mark_phys_offset;
+       u32 bch_type;
+       u32 rsrvd3[8]; /* Toggle NAND timing parameters */
+       u32 disbbm;
+       u32 bb_mark_spare_offset;
+       u32 rsrvd4[9]; /* ONFI NAND parameters */
+       u32 disbb_search;
+ };
+ struct mx6_dbbt_header {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       u32 number_bb;
+       u32 number_pages;
+       u8 spare[492];
+ };
+ struct mx6_dbbt {
+       u32 nand_number;
+       u32 number_bb;
+       u32 bb_num[2040 / 4];
+ };
+ #define BF_VAL(v, bf)         (((v) & bf##_MASK) >> bf##_OFFSET)
+ static nand_info_t *mtd = &nand_info[0];
+ extern void *_start;
+ #define BIT(v,n)      (((v) >> (n)) & 0x1)
+ static u8 calculate_parity_13_8(u8 d)
+ {
+       u8 p = 0;
+       p |= (BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 3) ^ BIT(d, 2))             << 0;
+       p |= (BIT(d, 7) ^ BIT(d, 5) ^ BIT(d, 4) ^ BIT(d, 2) ^ BIT(d, 1)) << 1;
+       p |= (BIT(d, 7) ^ BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 1) ^ BIT(d, 0)) << 2;
+       p |= (BIT(d, 7) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 0))             << 3;
+       p |= (BIT(d, 6) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 2) ^ BIT(d, 1) ^ BIT(d, 0)) << 4;
+       return p;
+ }
+ static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+ {
+       int i;
+       u8 *src = _src;
+       u8 *ecc = _ecc;
+       for (i = 0; i < size; i++)
+               ecc[i] = calculate_parity_13_8(src[i]);
+ }
+ static u32 calc_chksum(void *buf, size_t size)
+ {
+       u32 chksum = 0;
+       u8 *bp = buf;
+       size_t i;
+       for (i = 0; i < size; i++) {
+               chksum += bp[i];
+       }
+       return ~chksum;
+ }
+ /*
+   Physical organisation of data in NAND flash:
+   metadata
+   payload chunk 0 (may be empty)
+   ecc for metadata + payload chunk 0
+   payload chunk 1
+   ecc for payload chunk 1
+ ...
+   payload chunk n
+   ecc for payload chunk n
+  */
+ static inline int calc_bb_offset(nand_info_t *mtd, struct mx6_fcb *fcb)
+ {
+       int bb_mark_offset;
+       int chunk_data_size = fcb->ecc_blockn_size * 8;
+       int chunk_ecc_size = (fcb->ecc_blockn_type << 1) * 13;
+       int chunk_total_size = chunk_data_size + chunk_ecc_size;
+       int bb_mark_chunk, bb_mark_chunk_offs;
+       bb_mark_offset = (mtd->writesize - fcb->metadata_size) * 8;
+       if (fcb->ecc_block0_size == 0)
+               bb_mark_offset -= (fcb->ecc_block0_type << 1) * 13;
+       bb_mark_chunk = bb_mark_offset / chunk_total_size;
+       bb_mark_chunk_offs = bb_mark_offset - (bb_mark_chunk * chunk_total_size);
+       if (bb_mark_chunk_offs > chunk_data_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       bb_mark_offset -= bb_mark_chunk * chunk_ecc_size;
+       return bb_mark_offset;
+ }
+ /*
+  * return number of blocks to skip for a contiguous partition
+  * of given # blocks
+  */
+ static int find_contig_space(int block, int num_blocks, int max_blocks)
+ {
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+ }
+ #define pr_fcb_val(p, n)      debug("%s=%08x(%d)\n", #n, (p)->n, (p)->n)
+ static struct mx6_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+ {
+       struct gpmi_regs *gpmi_base = (void *)GPMI_BASE_ADDRESS;
+       struct bch_regs *bch_base = (void *)BCH_BASE_ADDRESS;
+       u32 fl0, fl1;
+       u32 t0;
+       int metadata_size;
+       int bb_mark_bit_offs;
+       struct mx6_fcb *fcb;
+       int fcb_offs;
+       if (gpmi_base == NULL || bch_base == NULL) {
+               return ERR_PTR(-ENOMEM);
+       }
+       fl0 = readl(&bch_base->hw_bch_flash0layout0);
+       fl1 = readl(&bch_base->hw_bch_flash0layout1);
+       t0 = readl(&gpmi_base->hw_gpmi_timing0);
+       metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb = buf + ALIGN(metadata_size, 4);
+       fcb_offs = (void *)fcb - buf;
+       memset(buf, 0xff, fcb_offs);
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - fcb_offs - sizeof(*fcb));
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = cpu_to_be32(1);
+       fcb->disbb_search = 0;
+       fcb->disbbm = 1;
+       /* ROM code assumes GPMI clock of 25 MHz */
+       fcb->timing.data_setup = BF_VAL(t0, GPMI_TIMING0_DATA_SETUP) * 40;
+       fcb->timing.data_hold = BF_VAL(t0, GPMI_TIMING0_DATA_HOLD) * 40;
+       fcb->timing.address_setup = BF_VAL(t0, GPMI_TIMING0_ADDRESS_SETUP) * 40;
+       fcb->page_data_size = mtd->writesize;
+       fcb->total_page_size = mtd->writesize + mtd->oobsize;
+       fcb->sectors_per_block = mtd->erasesize / mtd->writesize;
+       fcb->ecc_block0_type = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
+       fcb->ecc_block0_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE) * 4;
+       fcb->ecc_blockn_type = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
+       fcb->ecc_blockn_size = BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE) * 4;
+       pr_fcb_val(fcb, ecc_block0_type);
+       pr_fcb_val(fcb, ecc_blockn_type);
+       pr_fcb_val(fcb, ecc_block0_size);
+       pr_fcb_val(fcb, ecc_blockn_size);
+       fcb->metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb->ecc_blocks_per_page = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+       fcb->bch_mode = readl(&bch_base->hw_bch_mode);
+       fcb->bch_type = 0; /* BCH20 */
+       fcb->fw1_start_page = fw1_start_block * fcb->sectors_per_block;
+       fcb->fw1_sectors = fw_num_blocks * fcb->sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+       pr_fcb_val(fcb, fw1_sectors);
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * fcb->sectors_per_block;
+               fcb->fw2_sectors = fcb->fw1_sectors;
+               pr_fcb_val(fcb, fw2_start_page);
+               pr_fcb_val(fcb, fw2_sectors);
+       }
+       fcb->dbbt_search_area = 0;
+       bb_mark_bit_offs = calc_bb_offset(mtd, fcb);
+       if (bb_mark_bit_offs < 0)
+               return ERR_PTR(bb_mark_bit_offs);
+       fcb->bb_mark_byte = bb_mark_bit_offs / 8;
+       fcb->bb_mark_startbit = bb_mark_bit_offs % 8;
+       fcb->bb_mark_phys_offset = mtd->writesize;
+       pr_fcb_val(fcb, bb_mark_byte);
+       pr_fcb_val(fcb, bb_mark_startbit);
+       pr_fcb_val(fcb, bb_mark_phys_offset);
+       fcb->checksum = calc_chksum(&fcb->fingerprint, 512 - 4);
+       return fcb;
+ }
+ static int find_fcb(void *ref, int page)
+ {
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+ out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+ }
+ static int write_fcb(void *buf, int block)
+ {
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+       ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+       if (ret) {
+               printf("Failed to erase FCB block %u\n", block);
+               return ret;
+       }
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       chip->select_chip(mtd, 0);
++      ret = chip->write_page(mtd, chip, 0, mtd->writesize,
++                      buf, 1, page, 0, 1);
+       if (ret) {
+               printf("Failed to write FCB to block %u: %d\n", block, ret);
+       }
+       chip->select_chip(mtd, -1);
+       return ret;
+ }
+ struct mx6_ivt {
+       u32 magic;
+       u32 entry;
+       u32 rsrvd1;
+       void *dcd;
+       void *boot_data;
+       void *self;
+       void *csf;
+       u32 rsrvd2;
+ };
+ struct mx6_boot_data {
+       u32 start;
+       u32 length;
+       u32 plugin;
+ };
+ static int find_ivt(void *buf)
+ {
+       struct mx6_ivt *ivt_hdr = buf + 0x400;
+       if ((ivt_hdr->magic & 0xff0000ff) != 0x400000d1)
+               return 0;
+       return 1;
+ }
+ static inline void *reloc(void *dst, void *base, void *ptr)
+ {
+       return dst + (ptr - base);
+ }
+ static int patch_ivt(void *buf, size_t fsize)
+ {
+       struct mx6_ivt *ivt_hdr = buf + 0x400;
+       struct mx6_boot_data *boot_data;
+       if (!find_ivt(buf)) {
+               printf("No IVT found in image at %p\n", buf);
+               return -EINVAL;
+       }
+       boot_data = reloc(ivt_hdr, ivt_hdr->self, ivt_hdr->boot_data);
+       boot_data->length = fsize;
+       return 0;
+ }
+ #define chk_overlap(a,b)                              \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+ #define fail_if_overlap(a,b,m1,m2) do {                               \
+       if (chk_overlap(a, b)) {                                \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,     \
+                       m2, b##_start_block, b##_end_block);    \
+               return -EINVAL;                                 \
+       }                                                       \
+ } while (0)
+ static int tx6_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+ {
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = (start_block + skip) * mtd->erasesize;
+       erase_opts.offset = start_block * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       ret = nand_erase_opts(mtd, &erase_opts);
+       if (ret) {
+               printf("Failed to erase flash: %d\n", ret);
+               return ret;
+       }
+       printf("Programming flash @ %08llx..%08llx from %p\n",
+               (u64)start_block * mtd->erasesize,
+               (u64)start_block * mtd->erasesize + size - 1, addr);
+       actual = size;
+       ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                               prg_length, addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to program flash: %d\n", ret);
+               return ret;
+       }
+       if (actual < size) {
+               printf("Could only write %u of %u bytes\n", actual, size);
+               return -EIO;
+       }
+       return 0;
+ }
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #ifndef CONFIG_ENV_OFFSET_REDUND
+ #define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+ #else
+ #define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+ #endif
+ #endif
+ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx6_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+ #endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               printf("WARNING: Image size not specified; overwriting whole uboot partition\n");
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0) {
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       } else {
+               fw_num_blocks = part_info->size / mtd->erasesize -
+                       extra_blocks;
+               size = fw_num_blocks * mtd->erasesize;
+       }
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image\n",
+                       fw_num_blocks);
+               if (uboot_part) {
+ #ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+ #else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+ #endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       fw1_end_block = fw1_start_block + fw1_skip + fw_num_blocks - 1;
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image\n",
+                               fw_num_blocks);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       fw2_end_block = fw2_start_block + fw2_skip + fw_num_blocks - 1;
+ #ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+ #endif
+       fail_if_overlap(fcb, fw1, "FCB", "FW1");
+       if (fw2_set) {
+               fail_if_overlap(fcb, fw2, "FCB", "FW2");
+ #ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+ #endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+       fcb = create_fcb(buf, fw1_start_block + fw1_skip,
+                       fw2_start_block + fw2_skip, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+       encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+       ret = patch_ivt(addr, size);
+       if (ret) {
+               return ret;
+       }
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block + fw1_skip,
+               (u64)(fw1_start_block + fw1_skip) * mtd->erasesize);
+       ret = tx6_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+       if (fw2_start_block == 0) {
+               return ret;
+       }
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block + fw2_skip,
+               (u64)(fw2_start_block + fw2_skip) * mtd->erasesize);
+       ret = tx6_prog_uboot(addr, fw2_start_block, fw2_skip, fw_num_blocks,
+                       max_len2);
+       return ret;
+ }
+ U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\twrite bootloader image at block # (decimal)\n"
+       "\t-r\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\tspecify number of redundant blocks per boot loader image\n"
+       "\t\tonly valid if -f or -r specify a flash address rather than a partition name\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr}\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize}"
+       );
diff --combined board/karo/tx6/ltc3676.c
index 0000000000000000000000000000000000000000,0df71445fc83dfcef8685a22d4b38638b9be615b..c43e91430464a2c1e680c3f9f905aa8619709892
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,209 +1,224 @@@
 -#define VDD_IO_VAL            mV_to_regval(vout_to_vref(3300 * 10, 5))
 -#define VDD_IO_VAL_LP         mV_to_regval(vout_to_vref(3100 * 10, 5))
 -#define VDD_IO_VAL_2          mV_to_regval(vout_to_vref(3300 * 10, 5_2))
 -#define VDD_IO_VAL_2_LP               mV_to_regval(vout_to_vref(3100 * 10, 5_2))
 -#define VDD_SOC_VAL           mV_to_regval(vout_to_vref(1425 * 10, 6))
 -#define VDD_SOC_VAL_LP                mV_to_regval(vout_to_vref(900 * 10, 6))
 -#define VDD_DDR_VAL           mV_to_regval(vout_to_vref(1500 * 10, 7))
 -#define VDD_DDR_VAL_LP                mV_to_regval(vout_to_vref(1500 * 10, 7))
 -#define VDD_CORE_VAL          mV_to_regval(vout_to_vref(1425 * 10, 8))
 -#define VDD_CORE_VAL_LP               mV_to_regval(vout_to_vref(900 * 10, 8))
+ /*
+  * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <i2c.h>
+ #include <asm/io.h>
++#include <asm/arch/imx-regs.h>
+ #include "pmic.h"
+ #define LTC3676_BUCK1         0x01
+ #define LTC3676_BUCK2         0x02
+ #define LTC3676_BUCK3         0x03
+ #define LTC3676_BUCK4         0x04
+ #define LTC3676_DVB1A         0x0A
+ #define LTC3676_DVB1B         0x0B
+ #define LTC3676_DVB2A         0x0C
+ #define LTC3676_DVB2B         0x0D
+ #define LTC3676_DVB3A         0x0E
+ #define LTC3676_DVB3B         0x0F
+ #define LTC3676_DVB4A         0x10
+ #define LTC3676_DVB4B         0x11
+ #define LTC3676_MSKPG         0x13
+ #define LTC3676_CLIRQ         0x1f
+ #define LTC3676_BUCK_DVDT_FAST        (1 << 0)
+ #define LTC3676_BUCK_KEEP_ALIVE       (1 << 1)
+ #define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
+ #define LTC3676_BUCK_PHASE_SEL        (1 << 3)
+ #define LTC3676_BUCK_ENABLE_300       (1 << 4)
+ #define LTC3676_BUCK_PULSE_SKIP       (0 << 5)
+ #define LTC3676_BUCK_BURST_MODE       (1 << 5)
+ #define LTC3676_BUCK_CONTINUOUS       (2 << 5)
+ #define LTC3676_BUCK_ENABLE   (1 << 7)
+ #define LTC3676_PGOOD_MASK    (1 << 5)
+ #define LTC3676_MSKPG_BUCK1   (1 << 0)
+ #define LTC3676_MSKPG_BUCK2   (1 << 1)
+ #define LTC3676_MSKPG_BUCK3   (1 << 2)
+ #define LTC3676_MSKPG_BUCK4   (1 << 3)
+ #define LTC3676_MSKPG_LDO2    (1 << 5)
+ #define LTC3676_MSKPG_LDO3    (1 << 6)
+ #define LTC3676_MSKPG_LDO4    (1 << 7)
 -#define mV_to_regval(mV)      DIV_ROUND(((((mV) < 4125) ? 4125 : (mV)) - 4125), 125)
 -#define regval_to_mV(v)               (((v) * 125 + 4125))
++#define VDD_IO_VAL            mV_to_regval(vout_to_vref(3300, 5))
++#define VDD_IO_VAL_LP         mV_to_regval(vout_to_vref(3100, 5))
++#define VDD_IO_VAL_2          mV_to_regval(vout_to_vref(3300, 5_2))
++#define VDD_IO_VAL_2_LP               mV_to_regval(vout_to_vref(3100, 5_2))
++#define VDD_SOC_VAL           mV_to_regval(vout_to_vref(1425, 6))
++#define VDD_SOC_VAL_LP                mV_to_regval(vout_to_vref(900, 6))
++#define VDD_DDR_VAL           mV_to_regval(vout_to_vref(1500, 7))
++#define VDD_DDR_VAL_LP                mV_to_regval(vout_to_vref(1500, 7))
++#define VDD_CORE_VAL          mV_to_regval(vout_to_vref(1425, 8))
++#define VDD_CORE_VAL_LP               mV_to_regval(vout_to_vref(900, 8))
+ /* LDO1 */
+ #define R1_1                  470
+ #define R2_1                  150
+ /* LDO4 */
+ #define R1_4                  470
+ #define R2_4                  150
+ /* Buck1 */
+ #define R1_5                  390
+ #define R2_5                  110
+ #define R1_5_2                        470
+ #define R2_5_2                        150
+ /* Buck2 (SOC) */
+ #define R1_6                  150
+ #define R2_6                  180
+ /* Buck3 (DDR) */
+ #define R1_7                  150
+ #define R2_7                  140
+ /* Buck4 (CORE) */
+ #define R1_8                  150
+ #define R2_8                  180
+ /* calculate voltages in 10mV */
+ #define R1(idx)                       R1_##idx
+ #define R2(idx)                       R2_##idx
++#define v2r(v,n,m)            DIV_ROUND_UP(((((v) < (n)) ? (n) : (v)) - (n)), (m))
++#define r2v(r,n,m)            (((r) * (m) + (n)) / 10)
++
+ #define vout_to_vref(vout, idx)       ((vout) * R2(idx) / (R1(idx) + R2(idx)))
+ #define vref_to_vout(vref, idx)       DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
 -static int ltc3676_setup_regs(struct ltc3676_regs *r, size_t count)
++#define mV_to_regval(mV)      v2r((mV) * 10, 4125, 125)
++#define regval_to_mV(r)               r2v(r, 4125, 125)
+ static struct ltc3676_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+ } ltc3676_regs[] = {
+       { LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
+       { LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
+       { LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
+       { LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
+       { LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
+       { LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_CLIRQ, 0, }, /* clear interrupt status */
+ };
+ static struct ltc3676_regs ltc3676_regs_1[] = {
+       { LTC3676_DVB1B, VDD_IO_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB1A, VDD_IO_VAL, ~0x3f, },
+ };
+ static struct ltc3676_regs ltc3676_regs_2[] = {
+       { LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
+ };
+ static int tx6_rev_2(void)
+ {
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank5_regs *fuse = (void *)ocotp->bank[5].fuse_regs;
+       u32 pad_settings = readl(&fuse->pad_settings);
+       debug("Fuse pad_settings @ %p = %02x\n",
+               &fuse->pad_settings, pad_settings);
+       return pad_settings & 1;
+ }
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
++static int ltc3676_setup_regs(uchar slave_addr, struct ltc3676_regs *r,
++                      size_t count)
+ {
+       int ret;
+       int i;
+       for (i = 0; i < count; i++, r++) {
+ #ifdef DEBUG
+               unsigned char value;
 -              ret = i2c_write(CONFIG_SYS_I2C_SLAVE,
 -                              r->addr, 1, &r->val, 1);
++              ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+ #endif
 -int setup_pmic_voltages(void)
++              ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+       }
+       return 0;
+ }
 -      ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
 -      if (ret != 0) {
 -              printf("Failed to initialize I2C\n");
 -              return ret;
 -      }
 -
 -      ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
++int ltc3676_pmic_setup(uchar slave_addr)
+ {
+       int ret;
+       unsigned char value;
 -      ret = ltc3676_setup_regs(ltc3676_regs, ARRAY_SIZE(ltc3676_regs));
++      ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
 -      printf("VDDCORE set to %umV\n",
 -              DIV_ROUND(vref_to_vout(regval_to_mV(VDD_CORE_VAL), 8), 10));
 -      printf("VDDSOC  set to %umV\n",
 -              DIV_ROUND(vref_to_vout(regval_to_mV(VDD_SOC_VAL), 6), 10));
++      ret = ltc3676_setup_regs(slave_addr, ltc3676_regs,
++                              ARRAY_SIZE(ltc3676_regs));
+       if (ret)
+               return ret;
 -              ret = ltc3676_setup_regs(ltc3676_regs_2,
++      ret = i2c_read(slave_addr, LTC3676_DVB4A, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDCORE set to %umV\n",
++                      vref_to_vout(regval_to_mV(value), 8));
++      } else {
++              printf("Failed to read VDDCORE register setting\n");
++      }
++
++      ret = i2c_read(slave_addr, LTC3676_DVB2A, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDSOC  set to %umV\n",
++                      vref_to_vout(regval_to_mV(value), 6));
++      } else {
++              printf("Failed to read VDDSOC register setting\n");
++      }
+       if (tx6_rev_2()) {
 -              printf("VDDIO   set to %umV\n",
 -                      DIV_ROUND(vref_to_vout(
 -                                      regval_to_mV(VDD_IO_VAL_2), 5_2), 10));
++              ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_2,
+                               ARRAY_SIZE(ltc3676_regs_2));
 -              ret = ltc3676_setup_regs(ltc3676_regs_1,
++
++              ret = i2c_read(slave_addr, LTC3676_DVB1A, 1, &value, 1);
++              if (ret == 0) {
++                      printf("VDDIO   set to %umV\n",
++                              vref_to_vout(regval_to_mV(value), 5_2));
++              } else {
++                      printf("Failed to read VDDIO register setting\n");
++              }
+       } else {
++              ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_1,
+                               ARRAY_SIZE(ltc3676_regs_1));
+       }
+       return ret;
+ }
diff --combined board/karo/tx6/pmic.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2743dadd3232a1bd341bfeca2a33fe8b213b81fc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,52 @@@
++/*
++ * Copyright (C) 2015 Lothar Waßmann <LW@KARO-electronics.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * 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.
++ *
++ */
++
++#include <common.h>
++#include <errno.h>
++#include <i2c.h>
++
++#include "pmic.h"
++
++static struct {
++      uchar addr;
++      int (*init)(uchar addr);
++} i2c_addrs[] = {
++#ifdef CONFIG_LTC3676
++      { 0x3c, ltc3676_pmic_setup, },
++#endif
++#ifdef CONFIG_RN5T618
++      { 0x32, rn5t618_pmic_setup, },
++#endif
++#ifdef CONFIG_RN5T567
++      { 0x33, rn5t567_pmic_setup, },
++#endif
++};
++
++int tx6_pmic_init(void)
++{
++      int ret = -ENODEV;
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(i2c_addrs); i++) {
++              ret = i2c_probe(i2c_addrs[i].addr);
++              if (ret == 0) {
++                      i2c_addrs[i].init(i2c_addrs[i].addr);
++                      break;
++              }
++      }
++      return ret;
++}
diff --combined board/karo/tx6/pmic.h
index 0000000000000000000000000000000000000000,c1cc8db6e82684a7355bed7cecb5ca2b0f64f744..4786eefc9bac542afd98a1f7dcde1fd3ad9ca770
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,18 +1,22 @@@
 -int setup_pmic_voltages(void);
+ /*
+  * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
++int ltc3676_pmic_setup(uchar addr);
++int rn5t618_pmic_setup(uchar addr);
++int rn5t567_pmic_setup(uchar addr);
++
++int tx6_pmic_init(void);
diff --combined board/karo/tx6/rn5t567.c
index 0000000000000000000000000000000000000000,f089168bafb70dd4514aeac56d4e2b91ed99beb3..a4a58844e40d1cbb3d48d69b24ed73397f5b0dbb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,186 +1,157 @@@
 -#define VDD_RTC_VAL           mV_to_regval_rtc(3000 * 10)
 -#define VDD_HIGH_VAL          mV_to_regval3(3000 * 10)
 -#define VDD_HIGH_VAL_LP               mV_to_regval3(3000 * 10)
 -#define VDD_CORE_VAL          mV_to_regval(1425 * 10)
 -#define VDD_CORE_VAL_LP               mV_to_regval(900 * 10)
 -#define VDD_SOC_VAL           mV_to_regval(1425 * 10)
 -#define VDD_SOC_VAL_LP                mV_to_regval(900 * 10)
 -#define VDD_DDR_VAL           mV_to_regval(1500 * 10)
 -#define VDD_DDR_VAL_LP                mV_to_regval(1500 * 10)
+ /*
+  * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <i2c.h>
+ #include "pmic.h"
+ #define RN5T567_NOETIMSET     0x11
+ #define RN5T567_LDORTC1_SLOT  0x2a
+ #define RN5T567_DC1CTL                0x2c
+ #define RN5T567_DC1CTL2               0x2d
+ #define RN5T567_DC2CTL                0x2e
+ #define RN5T567_DC2CTL2               0x2f
+ #define RN5T567_DC3CTL                0x30
+ #define RN5T567_DC3CTL2               0x31
+ #define RN5T567_DC1DAC                0x36 /* CORE */
+ #define RN5T567_DC2DAC                0x37 /* SOC */
+ #define RN5T567_DC3DAC                0x38 /* DDR */
+ #define RN5T567_DC1DAC_SLP    0x3b
+ #define RN5T567_DC2DAC_SLP    0x3c
+ #define RN5T567_DC3DAC_SLP    0x3d
+ #define RN5T567_LDOEN1                0x44
+ #define RN5T567_LDODIS                0x46
+ #define RN5T567_LDOEN2                0x48
+ #define RN5T567_LDO3DAC               0x4e /* IO */
+ #define RN5T567_LDORTC1DAC    0x56 /* VBACKUP */
+ #define NOETIMSET_DIS_OFF_NOE_TIM     (1 << 3)
 -#define mV_to_regval(mV)      DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 125)
 -#define regval_to_mV(v)               (((v) * 125 + 6000))
++#define VDD_RTC_VAL           mV_to_regval_rtc(3000)
++#define VDD_HIGH_VAL          mV_to_regval3(3000)
++#define VDD_HIGH_VAL_LP               mV_to_regval3(3000)
++#define VDD_CORE_VAL          mV_to_regval(1350)              /* DCDC1 */
++#define VDD_CORE_VAL_LP               mV_to_regval(900)
++#define VDD_SOC_VAL           mV_to_regval(1350)              /* DCDC2 */
++#define VDD_SOC_VAL_LP                mV_to_regval(900)
++#define VDD_DDR_VAL           mV_to_regval(1350)              /* DCDC3 */
++#define VDD_DDR_VAL_LP                mV_to_regval(1350)
+ /* calculate voltages in 10mV */
++#define v2r(v,n,m)            DIV_ROUND_UP(((((v) < (n)) ? (n) : (v)) - (n)), (m))
++#define r2v(r,n,m)            (((r) * (m) + (n)) / 10)
++
+ /* DCDC1-3 */
 -#define mV_to_regval2(mV)     DIV_ROUND(((((mV) < 9000) ? 9000 : (mV)) - 9000), 250)
 -#define regval2_to_mV(v)      (((v) * 250 + 9000))
++#define mV_to_regval(mV)      v2r((mV) * 10, 6000, 125)
++#define regval_to_mV(r)               r2v(r, 6000, 125)
+ /* LDO1-2 */
 -#define mV_to_regval3(mV)     DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 250)
 -#define regval3_to_mV(v)      (((v) * 250 + 6000))
++#define mV_to_regval2(mV)     v2r((mV) * 10, 9000, 250)
++#define regval2_to_mV(r)      r2v(r, 9000, 250)
+ /* LDO3 */
 -#define mV_to_regval_rtc(mV)  DIV_ROUND(((((mV) < 17000) ? 17000 : (mV)) - 17000), 250)
 -#define regval_rtc_to_mV(v)   (((v) * 250 + 17000))
++#define mV_to_regval3(mV)     v2r((mV) * 10, 6000, 250)
++#define regval3_to_mV(r)      r2v(r, 6000, 250)
+ /* LDORTC */
 -#if 0
++#define mV_to_regval_rtc(mV)  v2r((mV) * 10, 17000, 250)
++#define regval_rtc_to_mV(r)   r2v(r, 17000, 250)
+ static struct rn5t567_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+ } rn5t567_regs[] = {
+       { RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
 -      { RN5T567_LDORTCDAC, VDD_RTC_VAL, },
+       { RN5T567_DC1DAC, VDD_CORE_VAL, },
+       { RN5T567_DC2DAC, VDD_SOC_VAL, },
+       { RN5T567_DC3DAC, VDD_DDR_VAL, },
+       { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+       { RN5T567_DC2DAC_SLP, VDD_SOC_VAL_LP, },
+       { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+       { RN5T567_LDOEN1, 0x01f, ~0x1f, },
+       { RN5T567_LDOEN2, 0x10, ~0x30, },
+       { RN5T567_LDODIS, 0x00, },
+       { RN5T567_LDO3DAC, VDD_HIGH_VAL, },
 -#endif
++      { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
+       { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
 -static struct rn5t567_regs debug_regs[] __maybe_unused = {
 -      { 0x00,  4, },
 -      { 0x09,  4, },
 -      { 0x10, 16, },
 -      { 0x25, 26, },
 -      { 0x44,  3, },
 -      { 0x4c,  5, },
 -      { 0x56,  1, },
 -      { 0x58,  5, },
 -      { 0x97,  2, },
 -      { 0xb0,  1, },
 -      { 0xbc,  1, },
 -};
 -
 -static int rn5t567_setup_regs(struct rn5t567_regs *r, size_t count)
+ };
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
++static int rn5t567_setup_regs(uchar slave_addr, struct rn5t567_regs *r,
++                      size_t count)
+ {
+       int ret;
+       int i;
+       for (i = 0; i < count; i++, r++) {
+ #ifdef DEBUG
+               unsigned char value;
 -//            value = (value & ~r->mask) | r->val;
 -              ret = i2c_write(CONFIG_SYS_I2C_SLAVE,
 -                              r->addr, 1, &r->val, 1);
++              ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+ #endif
 -#ifdef DEBUG
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
 -              printf("PMIC reg %02x is %02x\n", r->addr, value);
 -#endif
++              ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
 -#if 0
 -      for (i = 0; i < ARRAY_SIZE(debug_regs); i++) {
 -              int j;
 -
 -              r = &debug_regs[i];
 -              for (j = r->addr; j < r->addr + r->val; j++) {
 -                      unsigned char value;
 -
 -                      ret = i2c_read(CONFIG_SYS_I2C_SLAVE, j, 1, &value, 1);
 -                      printf("PMIC reg %02x = %02x\n",
 -                              j, value);
 -              }
 -      }
 -#endif
 -      debug("%s() complete\n", __func__);
+       }
 -int setup_pmic_voltages(void)
+       return 0;
+ }
 -      ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
 -      if (ret != 0) {
 -              printf("Failed to initialize I2C\n");
 -              return ret;
 -      }
 -
 -      ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
++int rn5t567_pmic_setup(uchar slave_addr)
+ {
+       int ret;
+       unsigned char value;
 -      ret = rn5t567_setup_regs(rn5t567_regs, ARRAY_SIZE(rn5t567_regs));
++      ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
 -      printf("VDDCORE set to %umV\n",
 -              DIV_ROUND(regval_to_mV(VDD_CORE_VAL), 10));
 -      printf("VDDSOC  set to %umV\n",
 -              DIV_ROUND(regval_to_mV(VDD_SOC_VAL), 10));
++      ret = rn5t567_setup_regs(slave_addr, rn5t567_regs,
++                              ARRAY_SIZE(rn5t567_regs));
+       if (ret)
+               return ret;
++      ret = i2c_read(slave_addr, RN5T567_DC1DAC, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDCORE set to %umV\n", regval_to_mV(value));
++      } else {
++              printf("Failed to read VDDCORE register setting\n");
++      }
++
++      ret = i2c_read(slave_addr, RN5T567_DC2DAC, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDSOC  set to %umV\n", regval_to_mV(value));
++      } else {
++              printf("Failed to read VDDSOC register setting\n");
++      }
+       return ret;
+ }
diff --combined board/karo/tx6/rn5t618.c
index 0000000000000000000000000000000000000000,06dffa858589fdd3b6beb1e8fe51e7e5910c4459..538dd5574ae54edd912d68b924c7b9f1289c1993
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,177 +1,155 @@@
 -#define VDD_RTC_VAL           mV_to_regval_rtc(3000 * 10)
 -#define VDD_HIGH_VAL          mV_to_regval3(3000 * 10)
 -#define VDD_HIGH_VAL_LP               mV_to_regval3(3000 * 10)
 -#define VDD_CORE_VAL          mV_to_regval(1425 * 10)
 -#define VDD_CORE_VAL_LP               mV_to_regval(900 * 10)
 -#define VDD_SOC_VAL           mV_to_regval(1425 * 10)
 -#define VDD_SOC_VAL_LP                mV_to_regval(900 * 10)
 -#define VDD_DDR_VAL           mV_to_regval(1500 * 10)
 -#define VDD_DDR_VAL_LP                mV_to_regval(1500 * 10)
+ /*
+  * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <i2c.h>
+ #include "pmic.h"
+ #define RN5T618_NOETIMSET     0x11
+ #define RN5T618_LDORTC1_SLOT  0x2a
+ #define RN5T618_DC1CTL                0x2c
+ #define RN5T618_DC1CTL2               0x2d
+ #define RN5T618_DC2CTL                0x2e
+ #define RN5T618_DC2CTL2               0x2f
+ #define RN5T618_DC3CTL                0x30
+ #define RN5T618_DC3CTL2               0x31
+ #define RN5T618_DC1DAC                0x36 /* CORE */
+ #define RN5T618_DC2DAC                0x37 /* SOC */
+ #define RN5T618_DC3DAC                0x38 /* DDR */
+ #define RN5T618_DC1DAC_SLP    0x3b
+ #define RN5T618_DC2DAC_SLP    0x3c
+ #define RN5T618_DC3DAC_SLP    0x3d
+ #define RN5T618_LDOEN1                0x44
+ #define RN5T618_LDODIS                0x46
+ #define RN5T618_LDOEN2                0x48
+ #define RN5T618_LDO3DAC               0x4e /* IO */
+ #define RN5T618_LDORTCDAC     0x56 /* VBACKUP */
 -#define mV_to_regval(mV)      DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 125)
 -#define regval_to_mV(v)               (((v) * 125 + 6000))
++#define VDD_RTC_VAL           mV_to_regval_rtc(3000)
++#define VDD_HIGH_VAL          mV_to_regval3(3000)
++#define VDD_HIGH_VAL_LP               mV_to_regval3(3000)
++#define VDD_CORE_VAL          mV_to_regval(1425)              /* DCDC1 */
++#define VDD_CORE_VAL_LP               mV_to_regval(900)
++#define VDD_SOC_VAL           mV_to_regval(1425)              /* DCDC2 */
++#define VDD_SOC_VAL_LP                mV_to_regval(900)
++#define VDD_DDR_VAL           mV_to_regval(1500)              /* DCDC3 */
++#define VDD_DDR_VAL_LP                mV_to_regval(1500)
+ /* calculate voltages in 10mV */
++#define v2r(v,n,m)            DIV_ROUND_UP(((((v) < (n)) ? (n) : (v)) - (n)), (m))
++#define r2v(r,n,m)            (((r) * (m) + (n)) / 10)
++
+ /* DCDC1-3 */
 -#define mV_to_regval2(mV)     DIV_ROUND(((((mV) < 9000) ? 9000 : (mV)) - 9000), 250)
 -#define regval2_to_mV(v)      (((v) * 250 + 9000))
++#define mV_to_regval(mV)      v2r((mV) * 10, 6000, 125)
++#define regval_to_mV(r)               r2v(r, 6000, 125)
+ /* LDO1-2 */
 -#define mV_to_regval3(mV)     DIV_ROUND(((((mV) < 6000) ? 6000 : (mV)) - 6000), 250)
 -#define regval3_to_mV(v)      (((v) * 250 + 6000))
++#define mV_to_regval2(mV)     v2r((mV) * 10, 9000, 250)
++#define regval2_to_mV(r)      r2v(r, 9000, 250)
+ /* LDO3 */
 -#define mV_to_regval_rtc(mV)  DIV_ROUND(((((mV) < 17000) ? 17000 : (mV)) - 17000), 250)
 -#define regval_rtc_to_mV(v)   (((v) * 250 + 17000))
++#define mV_to_regval3(mV)     v2r((mV) * 10, 6000, 250)
++#define regval3_to_mV(r)      r2v(r, 6000, 250)
+ /* LDORTC */
 -#if CONFIG_TX6_REV == 2
 -      { RN5T618_NOETIMSET, 0, },
 -      { RN5T618_DC1DAC, VDD_CORE_VAL, },
 -      { RN5T618_DC2DAC, VDD_SOC_VAL, },
 -      { RN5T618_DC3DAC, VDD_DDR_VAL, },
 -      { RN5T618_DC1DAC_SLP, VDD_CORE_VAL_LP, },
 -      { RN5T618_DC2DAC_SLP, VDD_SOC_VAL_LP, },
 -      { RN5T618_DC3DAC_SLP, VDD_DDR_VAL_LP, },
 -      { RN5T618_LDOEN1, 0x01f, ~0x1f, },
 -      { RN5T618_LDOEN2, 0x10, ~0x30, },
 -      { RN5T618_LDODIS, 0x00, },
 -      { RN5T618_LDO3DAC, VDD_HIGH_VAL, },
 -      { RN5T618_LDORTCDAC, VDD_RTC_VAL, },
 -      { RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, },
 -#elif CONFIG_TX6_REV == 3
++#define mV_to_regval_rtc(mV)  v2r((mV) * 10, 17000, 250)
++#define regval_rtc_to_mV(r)   r2v(r, 17000, 250)
+ static struct rn5t618_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+ } rn5t618_regs[] = {
 -#else
 -#error Unsupported TX6 module revision
 -#endif
+       { RN5T618_NOETIMSET, 0, },
+       { RN5T618_DC1DAC, VDD_CORE_VAL, },
+       { RN5T618_DC2DAC, VDD_SOC_VAL, },
+       { RN5T618_DC3DAC, VDD_DDR_VAL, },
+       { RN5T618_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+       { RN5T618_DC2DAC_SLP, VDD_SOC_VAL_LP, },
+       { RN5T618_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+       { RN5T618_LDOEN1, 0x01f, ~0x1f, },
+       { RN5T618_LDOEN2, 0x10, ~0x30, },
+       { RN5T618_LDODIS, 0x00, },
+       { RN5T618_LDO3DAC, VDD_HIGH_VAL, },
+       { RN5T618_LDORTCDAC, VDD_RTC_VAL, },
+       { RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, },
 -static int rn5t618_setup_regs(struct rn5t618_regs *r, size_t count)
+ };
 -      for (i = 0; i < count; i++, r++) {
 -              unsigned char value;
 -
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
 -              printf("PMIC reg %02x = %02x\n",
 -                      r->addr, value);
 -      }
++static int rn5t618_setup_regs(uchar slave_addr, struct rn5t618_regs *r,
++                      size_t count)
+ {
+       int ret;
+       int i;
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
+       for (i = 0; i < count; i++, r++) {
+ #ifdef DEBUG
+               unsigned char value;
 -              ret = i2c_write(CONFIG_SYS_I2C_SLAVE,
 -                              r->addr, 1, &r->val, 1);
++              ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+ #endif
 -#ifdef DEBUG
 -              ret = i2c_read(CONFIG_SYS_I2C_SLAVE, r->addr, 1, &value, 1);
 -              printf("PMIC reg %02x is %02x\n", r->addr, value);
 -#endif
++              ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
 -int setup_pmic_voltages(void)
+       }
+       return 0;
+ }
 -      ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
 -      if (ret != 0) {
 -              printf("Failed to initialize I2C\n");
 -              return ret;
 -      }
 -
 -      ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
++int rn5t618_pmic_setup(uchar slave_addr)
+ {
+       int ret;
+       unsigned char value;
 -      ret = rn5t618_setup_regs(rn5t618_regs, ARRAY_SIZE(rn5t618_regs));
++      ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
 -      printf("VDDCORE set to %umV\n",
 -              DIV_ROUND(regval_to_mV(VDD_CORE_VAL), 10));
 -      printf("VDDSOC  set to %umV\n",
 -              DIV_ROUND(regval_to_mV(VDD_SOC_VAL), 10));
++      ret = rn5t618_setup_regs(slave_addr, rn5t618_regs,
++                              ARRAY_SIZE(rn5t618_regs));
+       if (ret)
+               return ret;
++      ret = i2c_read(slave_addr, RN5T618_DC1DAC, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDCORE set to %umV\n", regval_to_mV(value));
++      } else {
++              printf("Failed to read VDDCORE register setting\n");
++      }
++
++      ret = i2c_read(slave_addr, RN5T618_DC2DAC, 1, &value, 1);
++      if (ret == 0) {
++              printf("VDDSOC  set to %umV\n", regval_to_mV(value));
++      } else {
++              printf("Failed to read VDDSOC register setting\n");
++      }
+       return ret;
+ }
diff --combined board/karo/tx6/tx6qdl.c
index 0000000000000000000000000000000000000000,1fa2d1f00c511d72b461804afe8832348b2d7838..03022b9669d425b08ff08ddcc39737134896e0ff
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1298 +1,1326 @@@
 - * Copyright (C) 2012,2013 Lothar Waßmann <LW@KARO-electronics.de>
+ /*
 -
++ * Copyright (C) 2012-2015 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
 -static const iomux_v3_cfg_t tx6qdl_pads[] = {
 -#ifndef CONFIG_NO_NAND
+ #include <common.h>
+ #include <errno.h>
+ #include <libfdt.h>
+ #include <fdt_support.h>
+ #include <lcd.h>
+ #include <netdev.h>
+ #include <mmc.h>
+ #include <fsl_esdhc.h>
+ #include <video_fb.h>
+ #include <ipu.h>
+ #include <mxcfb.h>
+ #include <i2c.h>
+ #include <linux/fb.h>
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <asm/arch/mx6-pins.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
+ #include <asm/arch/crm_regs.h>
+ #include <asm/arch/sys_proto.h>
+ #include "../common/karo.h"
+ #include "pmic.h"
++#define __data __attribute__((section(".data")))
++
+ #define TX6_FEC_RST_GPIO              IMX_GPIO_NR(7, 6)
+ #define TX6_FEC_PWR_GPIO              IMX_GPIO_NR(3, 20)
+ #define TX6_FEC_INT_GPIO              IMX_GPIO_NR(7, 1)
+ #define TX6_LED_GPIO                  IMX_GPIO_NR(2, 20)
+ #define TX6_LCD_PWR_GPIO              IMX_GPIO_NR(2, 31)
+ #define TX6_LCD_RST_GPIO              IMX_GPIO_NR(3, 29)
+ #define TX6_LCD_BACKLIGHT_GPIO                IMX_GPIO_NR(1, 1)
+ #define TX6_RESET_OUT_GPIO            IMX_GPIO_NR(7, 12)
+ #ifdef CONFIG_MX6_TEMPERATURE_MIN
+ #define TEMPERATURE_MIN                       CONFIG_MX6_TEMPERATURE_MIN
+ #else
+ #define TEMPERATURE_MIN                       (-40)
+ #endif
+ #ifdef CONFIG_MX6_TEMPERATURE_HOT
+ #define TEMPERATURE_HOT                       CONFIG_MX6_TEMPERATURE_HOT
+ #else
+ #define TEMPERATURE_HOT                       80
+ #endif
+ DECLARE_GLOBAL_DATA_PTR;
+ #define MUX_CFG_SION                  IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0)
 -      MX6_PAD_NANDF_CLE__RAWNAND_CLE,
 -      MX6_PAD_NANDF_ALE__RAWNAND_ALE,
 -      MX6_PAD_NANDF_WP_B__RAWNAND_RESETN,
 -      MX6_PAD_NANDF_RB0__RAWNAND_READY0,
 -      MX6_PAD_NANDF_CS0__RAWNAND_CE0N,
 -      MX6_PAD_SD4_CMD__RAWNAND_RDN,
 -      MX6_PAD_SD4_CLK__RAWNAND_WRN,
 -      MX6_PAD_NANDF_D0__RAWNAND_D0,
 -      MX6_PAD_NANDF_D1__RAWNAND_D1,
 -      MX6_PAD_NANDF_D2__RAWNAND_D2,
 -      MX6_PAD_NANDF_D3__RAWNAND_D3,
 -      MX6_PAD_NANDF_D4__RAWNAND_D4,
 -      MX6_PAD_NANDF_D5__RAWNAND_D5,
 -      MX6_PAD_NANDF_D6__RAWNAND_D6,
 -      MX6_PAD_NANDF_D7__RAWNAND_D7,
++enum {
++      MX6_PAD_DECL(GARBAGE, 0, 0, 0, 0, 0, 0)
++};
++
++static const iomux_v3_cfg_t const tx6qdl_pads[] = {
++      MX6_PAD_GARBAGE,
++#ifdef CONFIG_TX6_NAND_
+       /* NAND flash pads */
 -      MX6_PAD_GPIO_17__GPIO_7_12,
++      MX6_PAD_NANDF_CLE__NAND_CLE,
++      MX6_PAD_NANDF_ALE__NAND_ALE,
++      MX6_PAD_NANDF_WP_B__NAND_RESETN,
++      MX6_PAD_NANDF_RB0__NAND_READY0,
++      MX6_PAD_NANDF_CS0__NAND_CE0N,
++      MX6_PAD_SD4_CMD__NAND_RDN,
++      MX6_PAD_SD4_CLK__NAND_WRN,
++      MX6_PAD_NANDF_D0__NAND_D0,
++      MX6_PAD_NANDF_D1__NAND_D1,
++      MX6_PAD_NANDF_D2__NAND_D2,
++      MX6_PAD_NANDF_D3__NAND_D3,
++      MX6_PAD_NANDF_D4__NAND_D4,
++      MX6_PAD_NANDF_D5__NAND_D5,
++      MX6_PAD_NANDF_D6__NAND_D6,
++      MX6_PAD_NANDF_D7__NAND_D7,
+ #endif
+       /* RESET_OUT */
 -      MX6_PAD_SD3_DAT7__UART1_TXD,
 -      MX6_PAD_SD3_DAT6__UART1_RXD,
 -      MX6_PAD_SD3_DAT1__UART1_RTS,
 -      MX6_PAD_SD3_DAT0__UART1_CTS,
++      MX6_PAD_GPIO_17__GPIO7_IO12,
+       /* UART pads */
+ #if CONFIG_MXC_UART_BASE == UART1_BASE
 -      MX6_PAD_SD4_DAT4__UART2_RXD,
 -      MX6_PAD_SD4_DAT7__UART2_TXD,
 -      MX6_PAD_SD4_DAT5__UART2_RTS,
 -      MX6_PAD_SD4_DAT6__UART2_CTS,
++      MX6_PAD_SD3_DAT7__UART1_TX_DATA,
++      MX6_PAD_SD3_DAT6__UART1_RX_DATA,
++      MX6_PAD_SD3_DAT1__UART1_RTS_B,
++      MX6_PAD_SD3_DAT0__UART1_CTS_B,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART2_BASE
 -      MX6_PAD_EIM_D24__UART3_TXD,
 -      MX6_PAD_EIM_D25__UART3_RXD,
 -      MX6_PAD_SD3_RST__UART3_RTS,
 -      MX6_PAD_SD3_DAT3__UART3_CTS,
++      MX6_PAD_SD4_DAT4__UART2_RX_DATA,
++      MX6_PAD_SD4_DAT7__UART2_TX_DATA,
++      MX6_PAD_SD4_DAT5__UART2_RTS_B,
++      MX6_PAD_SD4_DAT6__UART2_CTS_B,
+ #endif
+ #if CONFIG_MXC_UART_BASE == UART3_BASE
 -      MX6_PAD_EIM_D20__GPIO_3_20 | MUX_CFG_SION, /* PHY POWER */
 -      MX6_PAD_SD3_DAT2__GPIO_7_6 | MUX_CFG_SION, /* PHY RESET */
 -      MX6_PAD_SD3_DAT4__GPIO_7_1, /* PHY INT */
++      MX6_PAD_EIM_D24__UART3_TX_DATA,
++      MX6_PAD_EIM_D25__UART3_RX_DATA,
++      MX6_PAD_SD3_RST__UART3_RTS_B,
++      MX6_PAD_SD3_DAT3__UART3_CTS_B,
+ #endif
+       /* internal I2C */
+       MX6_PAD_EIM_D28__I2C1_SDA,
+       MX6_PAD_EIM_D21__I2C1_SCL,
+       /* FEC PHY GPIO functions */
 -static const iomux_v3_cfg_t tx6qdl_fec_pads[] = {
++      MX6_PAD_EIM_D20__GPIO3_IO20 | MUX_CFG_SION, /* PHY POWER */
++      MX6_PAD_SD3_DAT2__GPIO7_IO06 | MUX_CFG_SION, /* PHY RESET */
++      MX6_PAD_SD3_DAT4__GPIO7_IO01, /* PHY INT */
+ };
 -      MX6_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
++static const iomux_v3_cfg_t const tx6qdl_fec_pads[] = {
+       /* FEC functions */
+       MX6_PAD_ENET_MDC__ENET_MDC,
+       MX6_PAD_ENET_MDIO__ENET_MDIO,
 -      MX6_PAD_ENET_RXD1__ENET_RDATA_1,
 -      MX6_PAD_ENET_RXD0__ENET_RDATA_0,
++      MX6_PAD_GPIO_16__ENET_REF_CLK,
+       MX6_PAD_ENET_RX_ER__ENET_RX_ER,
+       MX6_PAD_ENET_CRS_DV__ENET_RX_EN,
 -      MX6_PAD_ENET_TXD1__ENET_TDATA_1,
 -      MX6_PAD_ENET_TXD0__ENET_TDATA_0,
++      MX6_PAD_ENET_RXD1__ENET_RX_DATA1,
++      MX6_PAD_ENET_RXD0__ENET_RX_DATA0,
+       MX6_PAD_ENET_TX_EN__ENET_TX_EN,
 -static const struct gpio tx6qdl_gpios[] = {
 -      { TX6_RESET_OUT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "#RESET_OUT", },
 -      { TX6_FEC_PWR_GPIO, GPIOF_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
 -      { TX6_FEC_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "FEC PHY RESET", },
 -      { TX6_FEC_INT_GPIO, GPIOF_INPUT, "FEC PHY INT", },
++      MX6_PAD_ENET_TXD1__ENET_TX_DATA1,
++      MX6_PAD_ENET_TXD0__ENET_TX_DATA0,
+ };
 -static const char *tx6_mod_suffix;
++static const struct gpio const tx6qdl_gpios[] = {
++      { TX6_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "#RESET_OUT", },
++      { TX6_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
++      { TX6_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RESET", },
++      { TX6_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },
+ };
+ /*
+  * Functions
+  */
+ /* placed in section '.data' to prevent overwriting relocation info
+  * overlayed with bss
+  */
+ static u32 wrsr __attribute__((section(".data")));
+ #define WRSR_POR                      (1 << 4)
+ #define WRSR_TOUT                     (1 << 1)
+ #define WRSR_SFTW                     (1 << 0)
+ static void print_reset_cause(void)
+ {
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+       printf("Reset cause: ");
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+       printf("\n");
+ }
 -      ret = setup_pmic_voltages();
++static const char __data *tx6_mod_suffix;
+ static void tx6qdl_print_cpuinfo(void)
+ {
+       u32 cpurev = get_cpu_rev();
+       char *cpu_str = "?";
+       switch ((cpurev >> 12) & 0xff) {
+       case MXC_CPU_MX6SL:
+               cpu_str = "SL";
+               tx6_mod_suffix = "?";
+               break;
+       case MXC_CPU_MX6DL:
+               cpu_str = "DL";
+               tx6_mod_suffix = "U";
+               break;
+       case MXC_CPU_MX6SOLO:
+               cpu_str = "SOLO";
+               tx6_mod_suffix = "S";
+               break;
+       case MXC_CPU_MX6Q:
+               cpu_str = "Q";
+               tx6_mod_suffix = "Q";
+               break;
+       }
+       printf("CPU:   Freescale i.MX6%s rev%d.%d at %d MHz\n",
+               cpu_str,
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       print_reset_cause();
+ #ifdef CONFIG_MX6_TEMPERATURE_HOT
+       check_cpu_temperature(1);
+ #endif
+ }
+ int board_early_init_f(void)
+ {
+       gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads));
+       return 0;
+ }
+ #ifndef CONFIG_MX6_TEMPERATURE_HOT
+ static bool tx6_temp_check_enabled = true;
+ #else
+ #define tx6_temp_check_enabled        0
+ #endif
+ int board_init(void)
+ {
+       int ret;
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       gd->bd->bi_arch_number = -1;
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected; Skipping PMIC setup\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+ #ifndef CONFIG_MX6_TEMPERATURE_HOT
+               tx6_temp_check_enabled = false;
+ #endif
+               return 1;
+       }
 -#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                  \
++      ret = tx6_pmic_init();
+       if (ret) {
+               printf("Failed to setup PMIC voltages\n");
+               hang();
+       }
+       return 0;
+ }
+ int dram_init(void)
+ {
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               PHYS_SDRAM_1_SIZE);
+       return 0;
+ }
+ void dram_init_banksize(void)
+ {
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
+                       PHYS_SDRAM_1_SIZE);
+ #if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
+                       PHYS_SDRAM_2_SIZE);
+ #endif
+ }
+ #ifdef        CONFIG_CMD_MMC
 -      MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
++#define SD_PAD_CTRL (PAD_CTL_PUS_47K_UP |                     \
+       PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
+       PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+ static const iomux_v3_cfg_t mmc0_pads[] = {
 -      MX6_PAD_SD3_CMD__GPIO_7_2,
++      MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* SD1 CD */
 -      MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT0__USDHC2_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT1__USDHC2_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT2__USDHC2_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD2_DAT3__USDHC2_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
++      MX6_PAD_SD3_CMD__GPIO7_IO02,
+ };
+ static const iomux_v3_cfg_t mmc1_pads[] = {
 -      MX6_PAD_SD3_CLK__GPIO_7_3,
++      MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* SD2 CD */
 -#ifdef CONFIG_MMC_BOOT_SIZE
++      MX6_PAD_SD3_CLK__GPIO7_IO03,
+ };
 -      MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
++#ifdef CONFIG_TX6_EMMC
+ static const iomux_v3_cfg_t mmc3_pads[] = {
 -      MX6_PAD_NANDF_ALE__USDHC4_RST,
++      MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
++      MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* eMMC RESET */
 -#ifdef CONFIG_MMC_BOOT_SIZE
++      MX6_PAD_NANDF_ALE__SD4_RESET,
+ };
+ #endif
+ static struct tx6_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       enum mxc_clock clkid;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+ } tx6qdl_esdhc_cfg[] = {
 -      debug("SD card %d is %spresent\n",
++#ifdef CONFIG_TX6_EMMC
+       {
+               .pads = mmc3_pads,
+               .num_pads = ARRAY_SIZE(mmc3_pads),
+               .clkid = MXC_ESDHC4_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC4_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = -EINVAL,
+       },
+ #endif
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .clkid = MXC_ESDHC_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(7, 2),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .clkid = MXC_ESDHC2_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(7, 3),
+       },
+ };
+ static inline struct tx6_esdhc_cfg *to_tx6_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+ {
+       return container_of(cfg, struct tx6_esdhc_cfg, cfg);
+ }
+ int board_mmc_getcd(struct mmc *mmc)
+ {
+       struct tx6_esdhc_cfg *cfg = to_tx6_esdhc_cfg(mmc->priv);
+       if (cfg->cd_gpio < 0)
+               return 1;
 -              gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
++      debug("SD card %d is %spresent (GPIO %d)\n",
+               cfg - tx6qdl_esdhc_cfg,
 -                                      GPIOF_INPUT, "MMC CD");
++              gpio_get_value(cfg->cd_gpio) ? "NOT " : "",
++              cfg->cd_gpio);
+       return !gpio_get_value(cfg->cd_gpio);
+ }
+ int board_mmc_init(bd_t *bis)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(tx6qdl_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx6_esdhc_cfg *cfg = &tx6qdl_esdhc_cfg[i];
+               int ret;
+               cfg->cfg.sdhc_clk = mxc_get_clock(cfg->clkid);
+               imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads);
+               if (cfg->cd_gpio >= 0) {
+                       ret = gpio_request_one(cfg->cd_gpio,
 -      imx_iomux_v3_setup_multiple_pads(tx6qdl_fec_pads, ARRAY_SIZE(tx6qdl_fec_pads));
++                                      GPIOFLAG_INPUT, "MMC CD");
+                       if (ret) {
+                               printf("Error %d requesting GPIO%d_%d\n",
+                                       ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                               continue;
+                       }
+               }
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc))
+                       mmc_init(mmc);
+       }
+       return 0;
+ }
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_FEC_MXC
+ #define FEC_PAD_CTL   (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                       PAD_CTL_SRE_FAST)
+ #define FEC_PAD_CTL2  (PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+ #define GPIO_PAD_CTL  (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+ #ifndef ETH_ALEN
+ #define ETH_ALEN 6
+ #endif
+ int board_eth_init(bd_t *bis)
+ {
+       int ret;
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
 -      MX6_PAD_EIM_A18__GPIO_2_20,
++      imx_iomux_v3_setup_multiple_pads(tx6qdl_fec_pads,
++                                      ARRAY_SIZE(tx6qdl_fec_pads));
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX6_FEC_RST_GPIO, 1);
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+       return ret;
+ }
++
++static void tx6_init_mac(void)
++{
++      u8 mac[ETH_ALEN];
++
++      imx_get_mac_from_fuse(-1, mac);
++      if (!is_valid_ether_addr(mac)) {
++              printf("No valid MAC address programmed\n");
++              return;
++      }
++
++      printf("MAC addr from fuse: %pM\n", mac);
++      eth_setenv_enetaddr("ethaddr", mac);
++}
++#else
++static inline void tx6_init_mac(void)
++{
++}
+ #endif /* CONFIG_FEC_MXC */
+ enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+ };
+ static inline int calc_blink_rate(void)
+ {
+       if (!tx6_temp_check_enabled)
+               return CONFIG_SYS_HZ;
+       return CONFIG_SYS_HZ + CONFIG_SYS_HZ / 10 -
+               (check_cpu_temperature(0) - TEMPERATURE_MIN) * CONFIG_SYS_HZ /
+               (TEMPERATURE_HOT - TEMPERATURE_MIN);
+ }
+ void show_activity(int arg)
+ {
+       static int led_state = LED_STATE_INIT;
+       static int blink_rate;
+       static ulong last;
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX6_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+               blink_rate = calc_blink_rate();
+       } else {
+               if (get_timer(last) > blink_rate) {
+                       blink_rate = calc_blink_rate();
+                       last = get_timer_masked();
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX6_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX6_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+ }
+ static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
 -      MX6_PAD_EIM_D26__GPIO_3_26,
++      MX6_PAD_EIM_A18__GPIO2_IO20,
+       /* I2C bus on DIMM pins 40/41 */
+       MX6_PAD_GPIO_6__I2C3_SDA,
+       MX6_PAD_GPIO_3__I2C3_SCL,
+       /* TSC200x PEN IRQ */
 -      MX6_PAD_NANDF_CS2__GPIO_6_15, /* IRQ */
 -      MX6_PAD_EIM_A16__GPIO_2_22, /* RESET */
 -      MX6_PAD_EIM_A17__GPIO_2_21, /* WAKE */
++      MX6_PAD_EIM_D26__GPIO3_IO26,
+       /* EDT-FT5x06 Polytouch panel */
 -      MX6_PAD_EIM_D31__GPIO_3_31, /* VBUSEN */
 -      MX6_PAD_EIM_D30__GPIO_3_30, /* OC */
++      MX6_PAD_NANDF_CS2__GPIO6_IO15, /* IRQ */
++      MX6_PAD_EIM_A16__GPIO2_IO22, /* RESET */
++      MX6_PAD_EIM_A17__GPIO2_IO21, /* WAKE */
+       /* USBH1 */
 -      MX6_PAD_EIM_D23__GPIO_3_23, /* USBOTG ID */
 -      MX6_PAD_GPIO_7__GPIO_1_7, /* VBUSEN */
 -      MX6_PAD_GPIO_8__GPIO_1_8, /* OC */
++      MX6_PAD_EIM_D31__GPIO3_IO31, /* VBUSEN */
++      MX6_PAD_EIM_D30__GPIO3_IO30, /* OC */
+       /* USBOTG */
 -      { TX6_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
++      MX6_PAD_EIM_D23__GPIO3_IO23, /* USBOTG ID */
++      MX6_PAD_GPIO_7__GPIO1_IO07, /* VBUSEN */
++      MX6_PAD_GPIO_8__GPIO1_IO08, /* OC */
+ };
+ static const struct gpio stk5_gpios[] = {
 -      { IMX_GPIO_NR(3, 23), GPIOF_INPUT, "USBOTG ID", },
 -      { IMX_GPIO_NR(1, 8), GPIOF_INPUT, "USBOTG OC", },
 -      { IMX_GPIO_NR(1, 7), GPIOF_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
 -      { IMX_GPIO_NR(3, 30), GPIOF_INPUT, "USBH1 OC", },
 -      { IMX_GPIO_NR(3, 31), GPIOF_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
++      { TX6_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
 -      .vl_bpix = LCD_COLOR24,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
++      { IMX_GPIO_NR(3, 23), GPIOFLAG_INPUT, "USBOTG ID", },
++      { IMX_GPIO_NR(1, 8), GPIOFLAG_INPUT, "USBOTG OC", },
++      { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
++      { IMX_GPIO_NR(3, 30), GPIOFLAG_INPUT, "USBH1 OC", },
++      { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
+ };
+ #ifdef CONFIG_LCD
+ static u16 tx6_cmap[256];
+ vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1920,
+       .vl_row = 1080,
 -      MX6_PAD_EIM_D29__GPIO_3_29,
++      .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx6_cmap,
+ };
+ static struct fb_videomode tx6_fb_modes[] = {
+ #ifndef CONFIG_SYS_LVDS_IF
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET070001DM6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET070001DM6",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = 0,
+       },
+ #else
+       {
+               /* HannStar HSD100PXN1
+                * 202.7m mm x 152.06 mm display area.
+                */
+               .name           = "HSD100PXN1",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = KHZ2PICOS(65000),
+               .left_margin    = 0,
+               .hsync_len      = 0,
+               .right_margin   = 320,
+               .upper_margin   = 0,
+               .vsync_len      = 0,
+               .lower_margin   = 38,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ #endif
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+ };
+ static int lcd_enabled = 1;
+ static int lcd_bl_polarity;
+ static int lcd_backlight_polarity(void)
+ {
+       return lcd_bl_polarity;
+ }
+ void lcd_enable(void)
+ {
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+       karo_load_splashimage(1);
+       if (lcd_enabled) {
+               debug("Switching LCD on\n");
+               gpio_set_value(TX6_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX6_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+ }
+ void lcd_disable(void)
+ {
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+ }
+ void lcd_panel_disable(void)
+ {
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX6_LCD_RST_GPIO, 0);
+               gpio_set_value(TX6_LCD_PWR_GPIO, 0);
+       }
+ }
+ static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
 -      MX6_PAD_EIM_EB3__GPIO_2_31,
++      MX6_PAD_EIM_D29__GPIO3_IO29,
+       /* LCD POWER_ENABLE */
 -      MX6_PAD_GPIO_1__GPIO_1_1,
++      MX6_PAD_EIM_EB3__GPIO2_IO31,
+       /* LCD Backlight (PWM) */
 -      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
 -      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
 -      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
 -      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
 -      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
 -      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
 -      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
 -      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
 -      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
 -      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
 -      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
 -      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
 -      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
 -      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
 -      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
 -      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
 -      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
 -      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
 -      MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
 -      MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
 -      MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
 -      MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
 -      MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
 -      MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
 -      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSYNC */
 -      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSYNC */
++      MX6_PAD_GPIO_1__GPIO1_IO01,
+ #ifndef CONFIG_SYS_LVDS_IF
+       /* Display */
 -      { TX6_LCD_RST_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
 -      { TX6_LCD_PWR_GPIO, GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
 -      { TX6_LCD_BACKLIGHT_GPIO, GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
++      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
++      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
++      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
++      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
++      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
++      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
++      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
++      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
++      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
++      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
++      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
++      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
++      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
++      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
++      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
++      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
++      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
++      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
++      MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
++      MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
++      MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
++      MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
++      MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
++      MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
++      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* HSYNC */
++      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* VSYNC */
+       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* OE_ACD */
+       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* LSCLK */
+ #endif
+ };
+ static const struct gpio stk5_lcd_gpios[] = {
 -              panel_info.vl_bpix = LCD_COLOR24;
++      { TX6_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
++      { TX6_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
++      { TX6_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+ };
+ void lcd_ctrl_init(void *lcdbase)
+ {
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx6_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       unsigned long di_clk_rate = 65000000;
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 32:
+                                       case 24:
+                                               if (is_lvds())
+                                                       pix_fmt = IPU_PIX_FMT_LVDS888;
+                                               /* fallthru */
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+                                       case 18:
+                                               if (is_lvds()) {
+                                                       color_depth = val;
+                                                       break;
+                                               }
+                                               /* fallthru */
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx6_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
 -      gpio_request_one(IMX_GPIO_NR(4, 21), GPIOF_OUTPUT_INIT_HIGH,
++              panel_info.vl_bpix = LCD_COLOR32;
+       }
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+       if (p != &fb_mode) {
+               int ret;
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24;
+               break;
+       case 18:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666;
+               break;
+       case 16:
+               if (!is_lvds()) {
+                       pix_fmt = IPU_PIX_FMT_RGB565;
+                       break;
+               }
+               /* fallthru */
+       default:
+               lcd_enabled = 0;
+               printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD",
+                       lcd_bus_width);
+               return;
+       }
+       if (is_lvds()) {
+               int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0);
+               int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt);
+               uint32_t gpr2;
++              uint32_t gpr3;
+               if (lvds_chan_mask == 0) {
+                       printf("No LVDS channel active\n");
+                       lcd_enabled = 0;
+                       return;
+               }
+               gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8);
+               if (lcd_bus_width == 24)
+                       gpr2 |= (1 << 5) | (1 << 7);
+               gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0;
+               gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0;
+               debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8);
+               writel(gpr2, IOMUXC_BASE_ADDR + 8);
++
++              gpr3 = readl(IOMUXC_BASE_ADDR + 0xc);
++              gpr3 &= ~((3 << 8) | (3 << 6));
++              writel(gpr3, IOMUXC_BASE_ADDR + 0xc);
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt,
+                               is_lvds() ? DI_PCLK_LDB : DI_PCLK_PLL3,
+                               di_clk_rate, -1);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+ }
+ #else
+ #define lcd_enabled 0
+ #endif /* CONFIG_LCD */
+ static void stk5_board_init(void)
+ {
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+ }
+ static void stk5v3_board_init(void)
+ {
+       stk5_board_init();
+ }
+ static void stk5v5_board_init(void)
+ {
+       stk5_board_init();
 -      imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO_4_21);
++      gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
 -static void tx6_init_mac(void)
 -{
 -      u8 mac[ETH_ALEN];
 -
 -      imx_get_mac_from_fuse(-1, mac);
 -      if (!is_valid_ether_addr(mac)) {
 -              printf("No valid MAC address programmed\n");
 -              return;
 -      }
 -
 -      printf("MAC addr from fuse: %pM\n", mac);
 -      eth_setenv_enetaddr("ethaddr", mac);
 -}
 -
++      imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO4_IO21);
+ }
+ static void tx6qdl_set_cpu_clock(void)
+ {
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (wrsr & WRSR_TOUT) ? "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+       if (mxc_set_clock(CONFIG_SYS_MX6_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+ }
 -#ifdef CONFIG_NO_NAND
+ int board_late_init(void)
+ {
+       int ret = 0;
+       const char *baseboard;
+       env_cleanup();
+       if (tx6_temp_check_enabled)
+               check_cpu_temperature(1);
+       tx6qdl_set_cpu_clock();
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+       printf("Baseboard: %s\n", baseboard);
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+ exit:
+       tx6_init_mac();
+       gpio_set_value(TX6_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+ }
 -#define TX6_FLASH_SZ  (CONFIG_MMC_BOOT_SIZE / 1024 - 1 + 2)
++#ifdef CONFIG_TX6_NAND
++#define TX6_FLASH_SZ  (CONFIG_SYS_NAND_BLOCKS / 1024 - 1)
++#else
+ #ifdef CONFIG_MMC_BOOT_SIZE
 -#define TX6_FLASH_SZ  3
++#define TX6_FLASH_SZ  (CONFIG_MMC_BOOT_SIZE / 4096 + 2)
+ #else
 -#else /* CONFIG_NO_NAND */
 -#define TX6_FLASH_SZ  (CONFIG_SYS_NAND_BLOCKS / 1024 - 1)
 -#endif /* CONFIG_NO_NAND */
++#define TX6_FLASH_SZ  2
+ #endif
 -#ifdef CONFIG_SYS_SDRAM_BUS_WIDTH
 -#define TX6_DDR_SZ    (ffs(CONFIG_SYS_SDRAM_BUS_WIDTH / 16) - 1)
 -#else
 -#define TX6_DDR_SZ    2
 -#endif
++#endif /* CONFIG_TX6_NAND */
 -#if CONFIG_TX6_REV >= 0x3
++#define TX6_DDR_SZ    (ffs(PHYS_SDRAM_1_WIDTH / 16) - 1)
 -      '4', /* 256MiB SDRAM; 128MiB NAND */
 -      '1', /* 512MiB SDRAM; 128MiB NAND */
 -      '0', /* 1GiB SDRAM; 128MiB NAND */
 -      '?', /* 256MiB SDRAM; 256MiB NAND */
 -      '?', /* 512MiB SDRAM; 256MiB NAND */
 -      '2', /* 1GiB SDRAM; 256MiB NAND */
 -      '?', /* 256MiB SDRAM; 4GiB eMMC */
 -      '5', /* 512MiB SDRAM; 4GiB eMMC */
 -      '3', /* 1GiB SDRAM; 4GiB eMMC */
 -      '?', /* 256MiB SDRAM; 8GiB eMMC */
 -      '?', /* 512MiB SDRAM; 8GiB eMMC */
 -      '?', /* 1GiB SDRAM; 8GiB eMMC */
+ static char tx6_mem_table[] = {
 -#else /* CONFIG_TX6_REV >= 0x3 */
 -static inline char tx6_mem_suffix(void)
++      '4', /* 256MiB SDRAM 16bit; 128MiB NAND */
++      '1', /* 512MiB SDRAM 32bit; 128MiB NAND */
++      '0', /* 1GiB SDRAM 64bit; 128MiB NAND */
++      '?', /* 256MiB SDRAM 16bit; 256MiB NAND */
++      '?', /* 512MiB SDRAM 32bit; 256MiB NAND */
++      '2', /* 1GiB SDRAM 64bit; 256MiB NAND */
++      '?', /* 256MiB SDRAM 16bit; 4GiB eMMC */
++      '5', /* 512MiB SDRAM 32bit; 4GiB eMMC */
++      '3', /* 1GiB SDRAM 64bit; 4GiB eMMC */
++      '?', /* 256MiB SDRAM 16bit; 8GiB eMMC */
++      '?', /* 512MiB SDRAM 32bit; 8GiB eMMC */
++      '0', /* 1GiB SDRAM 64bit; 8GiB eMMC */
+ };
+ static inline char tx6_mem_suffix(void)
+ {
+       size_t mem_idx = (TX6_FLASH_SZ * 3) + TX6_DDR_SZ;
+       debug("TX6_DDR_SZ=%d TX6_FLASH_SZ=%d idx=%d\n",
+               TX6_DDR_SZ, TX6_FLASH_SZ, mem_idx);
+       if (mem_idx >= ARRAY_SIZE(tx6_mem_table))
+               return '?';
+       return tx6_mem_table[mem_idx];
+ };
 -#ifdef CONFIG_SYS_SDRAM_BUS_WIDTH
 -      if (CONFIG_SYS_SDRAM_BUS_WIDTH == 32)
 -              return '1';
 -#endif
 -#ifdef CONFIG_SYS_NAND_BLOCKS
 -      if (CONFIG_SYS_NAND_BLOCKS == 2048)
 -              return '2';
 -#endif
 -      return '0';
++
++static struct {
++      uchar addr;
++      uchar rev;
++} tx6_mod_revs[] = {
++      { 0x3c, 1, },
++      { 0x32, 2, },
++      { 0x33, 3, },
++};
++
++static int tx6_get_mod_rev(void)
+ {
 -#endif /* CONFIG_TX6_REV >= 0x3 */
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(tx6_mod_revs); i++) {
++              int ret = i2c_probe(tx6_mod_revs[i].addr);
++              if (ret == 0) {
++                      debug("I2C probe succeeded for addr %02x\n", tx6_mod_revs[i].addr);
++                      return tx6_mod_revs[i].rev;
++              }
++              debug("I2C probe returned %d for addr %02x\n", ret,
++                      tx6_mod_revs[i].addr);
++      }
++      return 0;
+ }
 -              is_lvds(), CONFIG_TX6_REV,
+ int checkboard(void)
+ {
+       u32 cpurev = get_cpu_rev();
+       int cpu_variant = (cpurev >> 12) & 0xff;
+       tx6qdl_print_cpuinfo();
++      i2c_init(CONFIG_SYS_I2C_SPEED, 0 /* unused */);
++
+       printf("Board: Ka-Ro TX6%s-%d%d%d%c\n",
+               tx6_mod_suffix,
+               cpu_variant == MXC_CPU_MX6Q ? 1 : 8,
 -void ft_board_setup(void *blob, bd_t *bd)
++              is_lvds(), tx6_get_mod_rev(),
+               tx6_mem_suffix());
+       return 0;
+ }
+ #ifdef CONFIG_SERIAL_TAG
+ void get_board_serial(struct tag_serialnr *serialnr)
+ {
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank0_regs *fuse = (void *)ocotp->bank[0].fuse_regs;
+       serialnr->low = readl(&fuse->cfg0);
+       serialnr->high = readl(&fuse->cfg1);
+ }
+ #endif
+ #if defined(CONFIG_OF_BOARD_SETUP)
+ #ifdef CONFIG_FDT_FIXUP_PARTITIONS
+ #include <jffs2/jffs2.h>
+ #include <mtd_node.h>
+ static struct node_info nodes[] = {
+       { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, },
+ };
+ #else
+ #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+ #endif
+ static const char *tx6_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "eeti,egalax_ts",
+ };
 -      if (ret)
++int ft_board_setup(void *blob, bd_t *bd)
+ {
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+       ret = fdt_increase_size(blob, 4096);
 -
++      if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
++              return ret;
++      }
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+       karo_fdt_fixup_touchpanel(blob, tx6_touchpanels,
+                               ARRAY_SIZE(tx6_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       karo_fdt_update_fb_mode(blob, video_mode);
++
++      return 0;
+ }
+ #endif /* CONFIG_OF_BOARD_SETUP */
index 0000000000000000000000000000000000000000,f845810b28fdc6f535b3c265411240390f7fea47..4578febfb434b753cc430a9d59a4a715cf368e09
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,100 +1,119 @@@
 -      _end = .;
+ /*
+  * (C) Copyright 2012  Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License as
+  * published by the Free Software Foundation; either version 2 of
+  * the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+ OUTPUT_ARCH(arm)
+ ENTRY(_start)
+ SECTIONS
+ {
+       . = 0x00000000;
+       .text :
+       {
+               *(.__image_copy_start)
++              *(.vectors)
+               CPUDIR/start.o (.text*)
+               . = 0x400;
+               KEEP(board/karo/tx6/lowlevel_init.o (.text*))
+               *(.text*)
+       }
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+       . = ALIGN(4);
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+       .rel.dyn :
+       {
+               *(.rel*)
+       }
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
++      .end :
++      {
++              *(.__end)
++      }
++
++      _image_binary_end = .;
+ /*
+  * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+  * __bss_base and __bss_limit are for linker only (overlay ordering)
+  */
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_limit = .;
+       }
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+  
++      .dynsym _image_binary_end : { *(.dynsym) }
++      .dynbss : { *(.dynbss) }
++      .dynstr : { *(.dynstr*) }
++      .dynamic : { *(.dynamic*) }
++      .plt : { *(.plt*) }
++      .interp : { *(.interp*) }
++      .gnu.hash : { *(.gnu.hash) }
++      .gnu : { *(.gnu*) }
++      .ARM.exidx : { *(.ARM.exidx*) }
++      .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
++
++/*
+       /DISCARD/ : { *(.bss*) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynsym*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.hash*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
++*/
+ }
index 1075c6589d5d2ecda1a94301ee4d2b6f32eb9434,2b9d4baaa0b1a0f3076cb5a9d375a76a8daad173..18158806f57066aef15e1430afb6ba1def9593c4
@@@ -1,6 -1,5 +1,6 @@@
  /*
   * Copyright (C) 2013 Freescale Semiconductor, Inc.
 + * Copyright (C) 2014 O.S. Systems Software LTDA.
   *
   * Author: Fabio Estevam <fabio.estevam@freescale.com>
   *
  #include <asm/arch/sys_proto.h>
  #include <asm/gpio.h>
  #include <asm/imx-common/iomux-v3.h>
 +#include <asm/imx-common/mxc_i2c.h>
  #include <asm/imx-common/boot_mode.h>
 +#include <asm/imx-common/video.h>
  #include <asm/io.h>
 -#include <asm/sizes.h>
 +#include <linux/sizes.h>
  #include <common.h>
  #include <fsl_esdhc.h>
 -#include <ipu_pixfmt.h>
  #include <mmc.h>
  #include <miiphy.h>
  #include <netdev.h>
 -#include <linux/fb.h>
 +#include <phy.h>
 +#include <input.h>
 +#include <i2c.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
  #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                 \
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  
 +#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
 +      PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
 +      PAD_CTL_ODE | PAD_CTL_SRE_FAST)
 +
  #define USDHC1_CD_GPIO                IMX_GPIO_NR(1, 2)
  #define USDHC3_CD_GPIO                IMX_GPIO_NR(3, 9)
  #define ETH_PHY_RESET         IMX_GPIO_NR(3, 29)
@@@ -59,50 -51,50 +59,50 @@@ int dram_init(void
  }
  
  static iomux_v3_cfg_t const uart1_pads[] = {
 -      MX6_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 -      MX6_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 +      MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  };
  
 -iomux_v3_cfg_t const usdhc1_pads[] = {
 -      MX6_PAD_SD1_CLK__USDHC1_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_CMD__USDHC1_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +static iomux_v3_cfg_t const usdhc1_pads[] = {
 +      MX6_PAD_SD1_CLK__SD1_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD1_CMD__SD1_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* Carrier MicroSD Card Detect */
-       MX6_PAD_GPIO_2__GPIO1_IO02      | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_GPIO_2__GPIO_1_2,
++      MX6_PAD_GPIO_2__GPIO1_IO02,
  };
  
  static iomux_v3_cfg_t const usdhc3_pads[] = {
 -      MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 -      MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CLK__SD3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_CMD__SD3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 +      MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* SOM MicroSD Card Detect */
-       MX6_PAD_EIM_DA9__GPIO3_IO09     | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_EIM_DA9__GPIO_3_9,
++      MX6_PAD_EIM_DA9__GPIO3_IO09,
  };
  
  static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TXC__RGMII_TXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD0__RGMII_TD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD1__RGMII_TD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD2__RGMII_TD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_TD3__RGMII_TD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 -      MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RXC__RGMII_RXC    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD0__RGMII_RD0    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD1__RGMII_RD1    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD2__RGMII_RD2    | MUX_PAD_CTRL(ENET_PAD_CTRL),
 +      MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_EIM_D29__GPIO3_IO29             | MUX_PAD_CTRL(NO_PAD_CTRL),
 -      MX6_PAD_EIM_D29__GPIO_3_29,
++      MX6_PAD_EIM_D29__GPIO3_IO29,
  };
  
  static void setup_iomux_uart(void)
@@@ -144,7 -136,7 +144,7 @@@ int board_mmc_getcd(struct mmc *mmc
  
  int board_mmc_init(bd_t *bis)
  {
 -      s32 status = 0;
 +      int ret;
        u32 index = 0;
  
        /*
                        printf("Warning: you configured more USDHC controllers"
                               "(%d) then supported by the board (%d)\n",
                               index + 1, CONFIG_SYS_FSL_USDHC_NUM);
 -                      return status;
 +                      return -EINVAL;
                }
  
 -              status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
 +              if (ret)
 +                      return ret;
        }
  
 -      return status;
 +      return 0;
  }
  
  static int mx6_rgmii_rework(struct phy_device *phydev)
@@@ -218,144 -208,98 +218,142 @@@ int board_phy_config(struct phy_device 
  }
  
  #if defined(CONFIG_VIDEO_IPUV3)
 -static void enable_hdmi(void)
 -{
 -      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 -      u8 reg;
 -      reg = readb(&hdmi->phy_conf0);
 -      reg |= HDMI_PHY_CONF0_PDZ_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -
 -      udelay(3000);
 -      reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -      udelay(3000);
 -      reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
 -      writeb(reg, &hdmi->phy_conf0);
 -      writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
 -}
 +struct i2c_pads_info i2c2_pad_info = {
 +      .scl = {
 +              .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL
 +                      | MUX_PAD_CTRL(I2C_PAD_CTRL),
 +              .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12
 +                      | MUX_PAD_CTRL(I2C_PAD_CTRL),
 +              .gp = IMX_GPIO_NR(4, 12)
 +      },
 +      .sda = {
 +              .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA
 +                      | MUX_PAD_CTRL(I2C_PAD_CTRL),
 +              .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13
 +                      | MUX_PAD_CTRL(I2C_PAD_CTRL),
 +              .gp = IMX_GPIO_NR(4, 13)
 +      }
 +};
  
 -static struct fb_videomode const hdmi = {
 -      .name           = "HDMI",
 -      .refresh        = 60,
 -      .xres           = 1024,
 -      .yres           = 768,
 -      .pixclock       = 15385,
 -      .left_margin    = 220,
 -      .right_margin   = 40,
 -      .upper_margin   = 21,
 -      .lower_margin   = 7,
 -      .hsync_len      = 60,
 -      .vsync_len      = 10,
 -      .sync           = FB_SYNC_EXT,
 -      .vmode          = FB_VMODE_NONINTERLACED
 +static iomux_v3_cfg_t const fwadapt_7wvga_pads[] = {
 +      MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
 +      MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* HSync */
 +      MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* VSync */
 +      MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04
 +              | MUX_PAD_CTRL(PAD_CTL_DSE_120ohm), /* Contrast */
 +      MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DISP0_DRDY */
 +
 +      MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
 +      MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
 +      MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
 +      MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
 +      MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
 +      MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
 +      MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
 +      MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
 +      MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
 +      MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
 +      MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
 +      MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
 +      MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
 +      MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
 +      MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
 +      MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
 +      MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
 +      MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
 +
-       MX6_PAD_SD4_DAT2__GPIO2_IO10
-               | MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_BKLEN */
-       MX6_PAD_SD4_DAT3__GPIO2_IO11
-               | MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_VDDEN */
++      MX6_PAD_SD4_DAT2__GPIO2_IO10, /* DISP0_BKLEN */
++      MX6_PAD_SD4_DAT3__GPIO2_IO11, /* DISP0_VDDEN */
  };
  
 -int board_video_skip(void)
 +static void do_enable_hdmi(struct display_info_t const *dev)
  {
 -      int ret;
 -
 -      ret = ipuv3_fb_init(&hdmi, 0, IPU_PIX_FMT_RGB24);
 +      imx_enable_hdmi_phy();
 +}
  
 -      if (ret)
 -              printf("HDMI cannot be configured: %d\n", ret);
 +static int detect_i2c(struct display_info_t const *dev)
 +{
 +      return (0 == i2c_set_bus_num(dev->bus)) &&
 +                      (0 == i2c_probe(dev->addr));
 +}
  
 -      enable_hdmi();
 +static void enable_fwadapt_7wvga(struct display_info_t const *dev)
 +{
 +      imx_iomux_v3_setup_multiple_pads(
 +              fwadapt_7wvga_pads,
 +              ARRAY_SIZE(fwadapt_7wvga_pads));
  
 -      return ret;
 +      gpio_direction_output(IMX_GPIO_NR(2, 10), 1);
 +      gpio_direction_output(IMX_GPIO_NR(2, 11), 1);
  }
  
 +struct display_info_t const displays[] = {{
 +      .bus    = -1,
 +      .addr   = 0,
 +      .pixfmt = IPU_PIX_FMT_RGB24,
 +      .detect = detect_hdmi,
 +      .enable = do_enable_hdmi,
 +      .mode   = {
 +              .name           = "HDMI",
 +              .refresh        = 60,
 +              .xres           = 1024,
 +              .yres           = 768,
 +              .pixclock       = 15385,
 +              .left_margin    = 220,
 +              .right_margin   = 40,
 +              .upper_margin   = 21,
 +              .lower_margin   = 7,
 +              .hsync_len      = 60,
 +              .vsync_len      = 10,
 +              .sync           = FB_SYNC_EXT,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} }, {
 +      .bus    = 1,
 +      .addr   = 0x10,
 +      .pixfmt = IPU_PIX_FMT_RGB666,
 +      .detect = detect_i2c,
 +      .enable = enable_fwadapt_7wvga,
 +      .mode   = {
 +              .name           = "FWBADAPT-LCD-F07A-0102",
 +              .refresh        = 60,
 +              .xres           = 800,
 +              .yres           = 480,
 +              .pixclock       = 33260,
 +              .left_margin    = 128,
 +              .right_margin   = 128,
 +              .upper_margin   = 22,
 +              .lower_margin   = 22,
 +              .hsync_len      = 1,
 +              .vsync_len      = 1,
 +              .sync           = 0,
 +              .vmode          = FB_VMODE_NONINTERLACED
 +} } };
 +size_t display_count = ARRAY_SIZE(displays);
 +
  static void setup_display(void)
  {
        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 -      struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
        int reg;
  
 -      /* Turn on IPU clock */
 -      reg = readl(&mxc_ccm->CCGR3);
 -      reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET;
 -      writel(reg, &mxc_ccm->CCGR3);
 -
 -      /* Turn on HDMI PHY clock */
 -      reg = readl(&mxc_ccm->CCGR2);
 -      reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
 -              | MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
 -      writel(reg, &mxc_ccm->CCGR2);
 -
 -      /* clear HDMI PHY reset */
 -      writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
 +      enable_ipu_clock();
 +      imx_setup_hdmi();
  
        reg = readl(&mxc_ccm->chsccdr);
 -      reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
 -              | MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
 -              | MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
        reg |= (CHSCCDR_CLK_SEL_LDB_DI0
 -              << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
 -            | (CHSCCDR_PODF_DIVIDE_BY_3
 -              << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 -            | (CHSCCDR_IPU_PRE_CLK_540M_PFD
 -              << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 +              << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
        writel(reg, &mxc_ccm->chsccdr);
 +
 +      /* Disable LCD backlight */
 +      imx_iomux_v3_setup_pad(MX6_PAD_DI0_PIN4__GPIO4_IO20);
 +      gpio_direction_input(IMX_GPIO_NR(4, 20));
  }
  #endif /* CONFIG_VIDEO_IPUV3 */
  
  int board_eth_init(bd_t *bis)
  {
 -      int ret;
 -
        setup_iomux_enet();
  
 -      ret = cpu_eth_init(bis);
 -      if (ret)
 -              printf("FEC MXC: %s:failed\n", __func__);
 -
 -      return 0;
 +      return cpu_eth_init(bis);
  }
  
  int board_early_init_f(void)
@@@ -399,8 -343,6 +397,8 @@@ int board_init(void
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  
 +      setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c2_pad_info);
 +
        return 0;
  }
  
diff --combined common/Kconfig
index fd84fa08bd3efc2569ac4200684f26abca5ac205,0000000000000000000000000000000000000000..72f7a07e96e069dc41b4bdbce94b51b963a8cca8
mode 100644,000000..100644
--- /dev/null
@@@ -1,316 -1,0 +1,384 @@@
 +menu "Command line interface"
 +      depends on !SPL_BUILD
 +
 +config HUSH_PARSER
 +      bool "Use hush shell"
 +      select SYS_HUSH_PARSER
 +      help
 +        This option enables the "hush" shell (from Busybox) as command line
 +        interpreter, thus enabling powerful command line syntax like
 +        if...then...else...fi conditionals or `&&' and '||'
 +        constructs ("shell scripts").
 +
 +        If disabled, you get the old, much simpler behaviour with a somewhat
 +        smaller memory footprint.
 +
 +config SYS_HUSH_PARSER
 +      bool
 +      help
 +        Backward compatibility.
 +
 +comment "Commands"
 +
 +menu "Info commands"
 +
 +config CMD_BDI
 +      bool "bdinfo"
 +      help
 +        Print board info
 +
 +config CMD_CONSOLE
 +      bool "coninfo"
 +      help
 +        Print console devices and information.
 +
 +config CMD_LICENSE
 +      bool "license"
 +      help
 +        Print GPL license text
 +
 +endmenu
 +
 +menu "Boot commands"
 +
 +config CMD_BOOTD
 +      bool "bootd"
 +      help
 +        Run the command stored in the environment "bootcmd", i.e.
 +        "bootd" does the same thing as "run bootcmd".
 +
 +config CMD_BOOTM
 +      bool "bootm"
 +      default y
 +      help
 +        Boot an application image from the memory.
 +
++config CMD_BOOTZ
++      bool "bootz"
++      default y
++      help
++        Boot a Linux kernel zImage.
++
++config CMD_BOOTCE
++      bool "bootce"
++      help
++        Boot a WindowsCE image.
++
 +config CMD_GO
 +      bool "go"
 +      default y
 +      help
 +        Start an application at a given address.
 +
 +config CMD_RUN
 +      bool "run"
 +      help
 +        Run the command in the given environment variable.
 +
 +config CMD_IMI
 +      bool "iminfo"
 +      help
 +        Print header information for application image.
 +
 +config CMD_IMLS
 +      bool "imls"
 +      help
 +        List all images found in flash
 +
 +config CMD_XIMG
 +      bool "imxtract"
 +      help
 +        Extract a part of a multi-image.
 +
 +endmenu
 +
++menu "DTB support"
++
++config OF_LIBFDT
++      bool "Enable FDT commands"
++
++config OF_BOARD_SETUP
++      bool "Support DT modifications by board code"
++      depends on OF_LIBFDT
++
++endmenu
++
 +menu "Environment commands"
 +
 +config CMD_EXPORTENV
 +      bool "env export"
 +      default y
 +      help
 +        Export environments.
 +
 +config CMD_IMPORTENV
 +      bool "env import"
 +      default y
 +      help
 +        Import environments.
 +
 +config CMD_EDITENV
 +      bool "editenv"
 +      help
 +        Edit environment variable.
 +
 +config CMD_SAVEENV
 +      bool "saveenv"
 +      help
 +        Run the command in the given environment variable.
 +
 +endmenu
 +
++menu "Environment configuration settings"
++
++choice
++      prompt "Select environment non-volatile storage"
++
++config ENV_IS_NOWHERE
++      bool "do not store environment"
++
++config ENV_IS_IN_NAND
++      bool "store environment in NAND"
++      depends on NAND
++
++config ENV_IS_IN_MMC
++      bool "store environment in MMC"
++      depends on MMC
++
++endchoice
++
++endmenu
++
 +menu "Memory commands"
 +
 +config CMD_MEMORY
 +      bool "md, mm, nm, mw, cp, cmp, base, loop"
 +      help
 +        Memeory commands.
 +          md - memory display
 +          mm - memory modify (auto-incrementing address)
 +          nm - memory modify (constant address)
 +          mw - memory write (fill)
 +          cp - memory copy
 +          cmp - memory compare
 +          base - print or set address offset
 +          loop - initinite loop on address range
 +
 +config CMD_CRC32
 +      bool "crc32"
 +      default y
 +      help
 +        Compute CRC32.
 +
 +config LOOPW
 +      bool "loopw"
 +      help
 +        Infinite write loop on address range
 +
 +config CMD_MEMTEST
 +      bool "crc32"
 +      help
 +        Simple RAM read/write test.
 +
 +config CMD_MX_CYCLIC
 +      bool "mdc, mwc"
 +      help
 +        mdc - memory display cyclic
 +        mwc - memory write cyclic
 +
 +config CMD_MEMINFO
 +      bool "meminfo"
 +      help
 +        Display memory information.
 +
 +endmenu
 +
 +menu "Device access commands"
 +
 +config CMD_LOADB
 +      bool "loadb"
 +      help
 +        Load a binary file over serial line.
 +
 +config CMD_LOADS
 +      bool "loads"
 +      help
 +        Load an S-Record file over serial line
 +
 +config CMD_FLASH
 +      bool "flinfo, erase, protect"
 +      help
 +        NOR flash support.
 +          flinfo - print FLASH memory information
 +          erase - FLASH memory
 +          protect - enable or disable FLASH write protection
 +
++config MTD_DEVICE
++      bool "MTD device support"
++
++config CMD_MTDPARTS
++      bool "MTD partitioning support"
++      default y
++      depends on MTD_DEVICE && (CMD_FLASH || CMD_NAND)
++
 +config CMD_NAND
 +      bool "nand"
 +      help
 +        NAND support.
 +
++config CMD_NAND_TRIMFFS
++      bool "Enable nand write.trimffs command"
++      help
++        Enable command to leave page sized runs of 0xff patterns in
++        erased state rather than overwriting them. This is required
++        for using NAND flash filesystems on NAND controllers with
++        a non-0xff ECC code for all 0xff data.
++
++config CMD_MMC
++      bool "mmc/sd"
++      help
++        MMC/SD support.
++
 +config CMD_SPI
 +      bool "sspi"
 +      help
 +        SPI utility command.
 +
 +config CMD_I2C
 +      bool "i2c"
 +      help
 +        I2C support.
 +
 +config CMD_USB
 +      bool "usb"
 +      help
 +        USB support.
 +
 +config CMD_FPGA
 +      bool "fpga"
 +      help
 +        FPGA support.
 +
 +endmenu
 +
 +
 +menu "Shell scripting commands"
 +
 +config CMD_ECHO
 +      bool "echo"
 +      help
 +        Echo args to console
 +
 +config CMD_ITEST
 +      bool "itest"
 +      help
 +        Return true/false on integer compare.
 +
 +config CMD_SOURCE
 +      bool "source"
 +      help
 +        Run script from memory
 +
 +endmenu
 +
 +menu "Network commands"
 +
 +config CMD_NET
 +      bool "bootp, tftpboot"
 +      help
 +        Network commands.
 +        bootp - boot image via network using BOOTP/TFTP protocol
 +        tftpboot - boot image via network using TFTP protocol
 +
 +config CMD_TFTPPUT
 +      bool "tftp put"
 +      help
 +        TFTP put command, for uploading files to a server
 +
 +config CMD_TFTPSRV
 +      bool "tftpsrv"
 +      help
 +        Act as a TFTP server and boot the first received file
 +
 +config CMD_RARP
 +      bool "rarpboot"
 +      help
 +        Boot image via network using RARP/TFTP protocol
 +
 +config CMD_DHCP
 +      bool "dhcp"
 +      help
 +        Boot image via network using DHCP/TFTP protocol
 +
 +config CMD_NFS
 +      bool "nfs"
 +      help
 +        Boot image via network using NFS protocol.
 +
 +config CMD_PING
 +      bool "ping"
 +      help
 +        Send ICMP ECHO_REQUEST to network host
 +
 +config CMD_CDP
 +      bool "cdp"
 +      help
 +        Perform CDP network configuration
 +
 +config CMD_SNTP
 +      bool "sntp"
 +      help
 +        Synchronize RTC via network
 +
 +config CMD_DNS
 +      bool "dns"
 +      help
 +        Lookup the IP of a hostname
 +
 +config CMD_DNS
 +      bool "dns"
 +      help
 +        Lookup the IP of a hostname
 +
 +config CMD_LINK_LOCAL
 +      bool "linklocal"
 +      help
 +        Acquire a network IP address using the link-local protocol
 +
 +endmenu
 +
 +menu "Misc commands"
 +
++config CMD_CACHE
++      bool "cache control"
++      help
++        Enable commands to switch data cache on/off.
++
 +config CMD_TIME
 +      bool "time"
 +      help
 +        Run commands and summarize execution time.
 +
 +# TODO: rename to CMD_SLEEP
 +config CMD_MISC
 +      bool "sleep"
 +      help
 +        Delay execution for some time
 +
 +config CMD_TIMER
 +      bool "timer"
 +      help
 +        Access the system timer.
 +
 +config CMD_SETGETDCR
 +      bool "getdcr, setdcr, getidcr, setidcr"
 +      depends on 4xx
 +      help
 +        getdcr - Get an AMCC PPC 4xx DCR's value
 +        setdcr - Set an AMCC PPC 4xx DCR's value
 +        getidcr - Get a register value via indirect DCR addressing
 +        setidcr - Set a register value via indirect DCR addressing
 +
 +endmenu
 +
 +endmenu
diff --combined common/Makefile
index c668a2fd5bceda028b8fb29cf0b5035160b16fbe,ca8b5f6931a446ad9ba376be75b091ba02b8fb9a..ca9a4b0dfc8780078fc8753c5a684144d8082652
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
 -include $(TOPDIR)/config.mk
 -
 -LIB   = $(obj)libcommon.o
 -
  # core
  ifndef CONFIG_SPL_BUILD
 -COBJS-y += main.o
 -COBJS-y += command.o
 -COBJS-y += exports.o
 -COBJS-y += hash.o
 -COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o
 -COBJS-y += s_record.o
 -COBJS-y += xyzModem.o
 -COBJS-y += cmd_disk.o
 +obj-y += main.o
 +obj-y += exports.o
 +obj-y += hash.o
 +ifdef CONFIG_SYS_HUSH_PARSER
 +obj-y += cli_hush.o
 +endif
 +
 +# This option is not just y/n - it can have a numeric value
 +ifdef CONFIG_BOOTDELAY
 +obj-y += autoboot.o
 +endif
 +
 +# This option is not just y/n - it can have a numeric value
 +ifdef CONFIG_BOOT_RETRY_TIME
 +obj-y += bootretry.o
 +endif
  
  # boards
 -COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
 -COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
 +obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
 +obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
  
  # core command
 -COBJS-y += cmd_boot.o
 -COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
 -COBJS-y += cmd_help.o
 -COBJS-y += cmd_version.o
 +obj-y += cmd_boot.o
 +obj-$(CONFIG_CMD_BOOTM) += cmd_bootm.o bootm.o bootm_os.o
 +obj-y += cmd_help.o
 +obj-y += cmd_version.o
  
  # environment
 -COBJS-y += env_attr.o
 -COBJS-y += env_callback.o
 -COBJS-y += env_flags.o
 -COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
 -COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
 -XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o
 -COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o
 -XCOBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o
 -COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o
 -COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 -COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
 -COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
 -COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 -COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
 -COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
 -COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 -COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
 -COBJS-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o
 -COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 +obj-y += env_attr.o
 +obj-y += env_callback.o
 +obj-y += env_flags.o
 +obj-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
 +obj-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
 +extra-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o
 +obj-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o
 +extra-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o
 +obj-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o
 +obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.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_NVRAM) += env_nvram.o
 +obj-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
 +obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 +obj-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
 +obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o
 +obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
  
  # command
 -COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
 -COBJS-$(CONFIG_SOURCE) += cmd_source.o
 -COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
 -COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 -COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
 -COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
 -COBJS-$(CONFIG_CMD_BOOTCE) += cmd_bootce.o
 -COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
 -COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 -COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
 -COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
 -COBJS-$(CONFIG_CMD_CBFS) += cmd_cbfs.o
 -COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
 -COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
 -COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
 -COBJS-$(CONFIG_CMD_DATE) += cmd_date.o
 -COBJS-$(CONFIG_CMD_SOUND) += cmd_sound.o
 +obj-$(CONFIG_CMD_AES) += cmd_aes.o
 +obj-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
 +obj-$(CONFIG_SOURCE) += cmd_source.o
 +obj-$(CONFIG_CMD_SOURCE) += cmd_source.o
 +obj-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 +obj-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
 +obj-$(CONFIG_CMD_BMP) += cmd_bmp.o
++obj-$(CONFIG_CMD_BOOTCE) += cmd_bootce.o
 +obj-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
 +obj-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 +obj-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
 +obj-$(CONFIG_CMD_CACHE) += cmd_cache.o
 +obj-$(CONFIG_CMD_CBFS) += cmd_cbfs.o
 +obj-$(CONFIG_CMD_CLK) += cmd_clk.o
 +obj-$(CONFIG_CMD_CONSOLE) += cmd_console.o
 +obj-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
 +obj-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
 +obj-$(CONFIG_CMD_DATE) += cmd_date.o
 +obj-$(CONFIG_CMD_DEMO) += cmd_demo.o
 +obj-$(CONFIG_CMD_SOUND) += cmd_sound.o
  ifdef CONFIG_4xx
 -COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o
 +obj-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o
  endif
  ifdef CONFIG_POST
 -COBJS-$(CONFIG_CMD_DIAG) += cmd_diag.o
 +obj-$(CONFIG_CMD_DIAG) += cmd_diag.o
  endif
 -COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o
 -COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o
 -COBJS-$(CONFIG_CMD_ECHO) += cmd_echo.o
 -COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
 -COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
 -COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
 -COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
 -COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
 -COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
 -COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
 -COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
 -COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
 -COBJS-$(CONFIG_CMD_FDOS) += cmd_fdos.o
 -COBJS-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o
 -COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o
 +obj-$(CONFIG_CMD_DISPLAY) += cmd_display.o
 +obj-$(CONFIG_CMD_DTT) += cmd_dtt.o
 +obj-$(CONFIG_CMD_ECHO) += cmd_echo.o
 +obj-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
 +obj-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
 +obj-$(CONFIG_CMD_ELF) += cmd_elf.o
 +obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
 +obj-$(CONFIG_CMD_EXT4) += cmd_ext4.o
 +obj-$(CONFIG_CMD_EXT2) += cmd_ext2.o
 +obj-$(CONFIG_CMD_FAT) += cmd_fat.o
 +obj-$(CONFIG_CMD_FDC) += cmd_fdc.o
 +obj-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
 +obj-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o
 +obj-$(CONFIG_CMD_FLASH) += cmd_flash.o
  ifdef CONFIG_FPGA
 -COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
 +obj-$(CONFIG_CMD_FPGA) += cmd_fpga.o
  endif
 -COBJS-$(CONFIG_CMD_FPGAD) += cmd_fpgad.o
 -COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
 -COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o
 -COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
 -COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 -COBJS-$(CONFIG_CMD_IIM) += cmd_iim.o
 -COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
 -COBJS-$(CONFIG_CMD_HASH) += cmd_hash.o
 -COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
 -COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o
 -COBJS-$(CONFIG_CMD_INI) += cmd_ini.o
 -COBJS-$(CONFIG_CMD_IRQ) += cmd_irq.o
 -COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o
 -COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o
 -COBJS-$(CONFIG_CMD_CRAMFS) += cmd_cramfs.o
 -COBJS-$(CONFIG_CMD_LDRINFO) += cmd_ldrinfo.o
 -COBJS-$(CONFIG_CMD_LED) += cmd_led.o
 -COBJS-$(CONFIG_CMD_LICENSE) += cmd_license.o
 -COBJS-y += cmd_load.o
 -COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
 -COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o
 -COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o
 -COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o
 -COBJS-$(CONFIG_CMD_IO) += cmd_io.o
 -COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
 -COBJS-$(CONFIG_MII) += miiphyutil.o
 -COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 -COBJS-$(CONFIG_PHYLIB) += miiphyutil.o
 -COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 +obj-$(CONFIG_CMD_FPGAD) += cmd_fpgad.o
 +obj-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
 +obj-$(CONFIG_CMD_FUSE) += cmd_fuse.o
 +obj-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
 +obj-$(CONFIG_CMD_GPIO) += cmd_gpio.o
 +obj-$(CONFIG_CMD_I2C) += cmd_i2c.o
 +obj-$(CONFIG_CMD_IOTRACE) += cmd_iotrace.o
 +obj-$(CONFIG_CMD_HASH) += cmd_hash.o
 +obj-$(CONFIG_CMD_IDE) += cmd_ide.o
 +obj-$(CONFIG_CMD_IMMAP) += cmd_immap.o
 +obj-$(CONFIG_CMD_INI) += cmd_ini.o
 +obj-$(CONFIG_CMD_IRQ) += cmd_irq.o
 +obj-$(CONFIG_CMD_ITEST) += cmd_itest.o
 +obj-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o
 +obj-$(CONFIG_CMD_CRAMFS) += cmd_cramfs.o
 +obj-$(CONFIG_CMD_LDRINFO) += cmd_ldrinfo.o
 +obj-$(CONFIG_CMD_LED) += cmd_led.o
 +obj-$(CONFIG_CMD_LICENSE) += cmd_license.o
 +obj-y += cmd_load.o
 +obj-$(CONFIG_LOGBUFFER) += cmd_log.o
 +obj-$(CONFIG_ID_EEPROM) += cmd_mac.o
 +obj-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o
 +obj-$(CONFIG_CMD_MEMORY) += cmd_mem.o
 +obj-$(CONFIG_CMD_IO) += cmd_io.o
 +obj-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
 +obj-$(CONFIG_MII) += miiphyutil.o
 +obj-$(CONFIG_CMD_MII) += miiphyutil.o
 +obj-$(CONFIG_PHYLIB) += miiphyutil.o
 +obj-$(CONFIG_CMD_MII) += cmd_mii.o
  ifdef CONFIG_PHYLIB
 -COBJS-$(CONFIG_CMD_MII) += cmd_mdio.o
 +obj-$(CONFIG_CMD_MII) += cmd_mdio.o
  endif
 -COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 -COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
 -COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 -COBJS-$(CONFIG_MP) += cmd_mp.o
 -COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 -COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
 -COBJS-$(CONFIG_CMD_NET) += cmd_net.o
 -COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
 -COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o
 -COBJS-$(CONFIG_CMD_PART) += cmd_part.o
 -COBJS-$(CONFIG_CMD_PATA) += cmd_pata.o
 +obj-$(CONFIG_CMD_MISC) += cmd_misc.o
 +obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
 +obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 +obj-$(CONFIG_MP) += cmd_mp.o
 +obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 +obj-$(CONFIG_CMD_NAND) += cmd_nand.o
 +obj-$(CONFIG_CMD_NET) += cmd_net.o
 +obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
 +obj-$(CONFIG_CMD_OTP) += cmd_otp.o
 +obj-$(CONFIG_CMD_PART) += cmd_part.o
  ifdef CONFIG_PCI
 -COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o
 +obj-$(CONFIG_CMD_PCI) += cmd_pci.o
 +endif
 +obj-y += cmd_pcmcia.o
 +obj-$(CONFIG_CMD_PORTIO) += cmd_portio.o
 +obj-$(CONFIG_CMD_PXE) += cmd_pxe.o
 +obj-$(CONFIG_CMD_READ) += cmd_read.o
 +obj-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
 +obj-$(CONFIG_CMD_REISER) += cmd_reiser.o
 +obj-$(CONFIG_SANDBOX) += cmd_sandbox.o
 +obj-$(CONFIG_CMD_SATA) += cmd_sata.o
 +obj-$(CONFIG_CMD_SF) += cmd_sf.o
 +obj-$(CONFIG_CMD_SCSI) += cmd_scsi.o
 +obj-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o
 +obj-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o
 +obj-$(CONFIG_CMD_SOFTSWITCH) += cmd_softswitch.o
 +obj-$(CONFIG_CMD_SPI) += cmd_spi.o
 +obj-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o
 +obj-$(CONFIG_CMD_STRINGS) += cmd_strings.o
 +obj-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
 +obj-$(CONFIG_CMD_TIME) += cmd_time.o
 +obj-$(CONFIG_CMD_TRACE) += cmd_trace.o
 +obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_test.o
 +obj-$(CONFIG_CMD_TPM) += cmd_tpm.o
 +obj-$(CONFIG_CMD_TSI148) += cmd_tsi148.o
 +obj-$(CONFIG_CMD_UBI) += cmd_ubi.o
 +obj-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o
 +obj-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 +obj-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
 +ifdef CONFIG_LZMA
 +obj-$(CONFIG_CMD_LZMADEC) += cmd_lzmadec.o
  endif
 -COBJS-y += cmd_pcmcia.o
 -COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o
 -COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o
 -COBJS-$(CONFIG_CMD_READ) += cmd_read.o
 -COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
 -COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
 -COBJS-$(CONFIG_SANDBOX) += cmd_sandbox.o
 -COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o
 -COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
 -COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o
 -COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o
 -COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o
 -COBJS-$(CONFIG_CMD_SOFTSWITCH) += cmd_softswitch.o
 -COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o
 -COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o
 -COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o
 -COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
 -COBJS-$(CONFIG_CMD_TIME) += cmd_time.o
 -COBJS-$(CONFIG_CMD_TRACE) += cmd_trace.o
 -COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_test.o
 -COBJS-$(CONFIG_CMD_TPM) += cmd_tpm.o
 -COBJS-$(CONFIG_CMD_TSI148) += cmd_tsi148.o
 -COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o
 -COBJS-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o
 -COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 -COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
  ifdef CONFIG_CMD_USB
 -COBJS-y += cmd_usb.o
 -COBJS-y += usb.o usb_hub.o
 -COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
 +obj-y += cmd_usb.o
 +obj-y += usb.o usb_hub.o
 +obj-$(CONFIG_USB_STORAGE) += usb_storage.o
  endif
 -COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
 -COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 -COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
 -COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
 -COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o
 -COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o
 +obj-$(CONFIG_CMD_FASTBOOT) += cmd_fastboot.o
 +obj-$(CONFIG_CMD_FS_UUID) += cmd_fs_uuid.o
 +
 +obj-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
 +obj-$(CONFIG_CMD_THOR_DOWNLOAD) += cmd_thordown.o
 +obj-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 +obj-$(CONFIG_YAFFS2) += cmd_yaffs2.o
 +obj-$(CONFIG_CMD_SPL) += cmd_spl.o
 +obj-$(CONFIG_CMD_ZIP) += cmd_zip.o
 +obj-$(CONFIG_CMD_ZFS) += cmd_zfs.o
  
  # others
 -COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
 -COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
 -COBJS-y += flash.o
 -COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
 -COBJS-$(CONFIG_I2C_EDID) += edid.o
 -COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
 -COBJS-y += splash.o
 -COBJS-$(CONFIG_LCD) += lcd.o
 -COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
 -COBJS-$(CONFIG_MENU) += menu.o
 -COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 -COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 -COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 -COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
 -COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
 +obj-$(CONFIG_BOOTSTAGE) += bootstage.o
 +obj-$(CONFIG_CONSOLE_MUX) += iomux.o
 +obj-y += flash.o
 +obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
 +obj-$(CONFIG_I2C_EDID) += edid.o
 +obj-$(CONFIG_KALLSYMS) += kallsyms.o
 +obj-y += splash.o
 +obj-$(CONFIG_LCD) += lcd.o
 +obj-$(CONFIG_LYNXKDI) += lynxkdi.o
 +obj-$(CONFIG_MENU) += menu.o
 +obj-$(CONFIG_MODEM_SUPPORT) += modem.o
 +obj-$(CONFIG_UPDATE_TFTP) += update.o
 +obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 +obj-$(CONFIG_CMD_DFU) += cmd_dfu.o
 +obj-$(CONFIG_CMD_GPT) += cmd_gpt.o
  endif
  
  ifdef CONFIG_SPL_BUILD
 -COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 -COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 -COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
 +obj-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 +obj-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
 +obj-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
 +ifdef CONFIG_SPL_USB_HOST_SUPPORT
 +obj-$(CONFIG_SPL_USB_SUPPORT) += usb.o usb_hub.o
 +obj-$(CONFIG_USB_STORAGE) += usb_storage.o
 +endif
 +ifdef CONFIG_SPL_SATA_SUPPORT
 +obj-$(CONFIG_CMD_SCSI) += cmd_scsi.o
 +endif
  # environment
 -COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_attr.o
 -COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_flags.o
 -COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_callback.o
 -ifneq ($(CONFIG_SPL_NET_SUPPORT),y)
 -COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
 -COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
 -COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
 -COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
 -COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
 -else
 -COBJS-y += env_nowhere.o
 +ifdef CONFIG_SPL_ENV_SUPPORT
 +obj-$(CONFIG_SPL_ENV_SUPPORT) += env_attr.o
 +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
  endif
  endif
  # core command
 -COBJS-y += cmd_nvedit.o
 +obj-y += cmd_nvedit.o
  #environment
 -COBJS-y += env_common.o
 +obj-y += env_common.o
  #others
 -ifdef CONFIG_DDR_SPD
 -SPD := y
 -endif
 -ifdef CONFIG_SPD_EEPROM
 -SPD := y
 +obj-$(CONFIG_DDR_SPD) += ddr_spd.o
 +obj-$(CONFIG_SPD_EEPROM) += ddr_spd.o
 +obj-$(CONFIG_HWCONFIG) += hwconfig.o
 +obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
 +obj-y += console.o
 +obj-$(CONFIG_CROS_EC) += cros_ec.o
 +obj-y += dlmalloc.o
 +ifdef CONFIG_SYS_MALLOC_F_LEN
 +obj-y += malloc_simple.o
  endif
 -COBJS-$(SPD) += ddr_spd.o
 -COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
 -COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
 -COBJS-y += console.o
 -COBJS-y += dlmalloc.o
 -COBJS-y += image.o
 -COBJS-$(CONFIG_OF_LIBFDT) += image-fdt.o
 -COBJS-$(CONFIG_FIT) += image-fit.o
 -COBJS-$(CONFIG_FIT_SIGNATURE) += image-sig.o
 -COBJS-y += memsize.o
 -COBJS-y += stdio.o
 -
 -
 -COBJS := $(sort $(COBJS-y))
 -XCOBJS        := $(sort $(XCOBJS-y))
 -SRCS  := $(COBJS:.o=.c) $(XCOBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -XOBJS := $(addprefix $(obj),$(XCOBJS))
 -
 -CPPFLAGS += -I..
 -
 -all:  $(LIB) $(XOBJS)
 -
 -$(LIB): $(obj).depend $(OBJS)
 -      $(call cmd_link_o_target, $(OBJS))
 -
 -$(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc
 -      $(CC) $(AFLAGS) -Wa,--no-warn \
 -              -DENV_CRC=$(shell $(obj)../tools/envcrc) \
 -              -c -o $@ $(src)env_embedded.c
 -
 -$(obj)../tools/envcrc:
 -      $(MAKE) -C ../tools
 +obj-y += image.o
 +obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 +obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
 +obj-$(CONFIG_FIT) += image-fit.o
 +obj-$(CONFIG_FIT_SIGNATURE) += image-sig.o
 +obj-$(CONFIG_IO_TRACE) += iotrace.o
 +obj-y += memsize.o
 +obj-y += stdio.o
  
 -# SEE README.arm-unaligned-accesses
 -$(obj)cmd_bmp.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
 -$(obj)fdt_support.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
 -$(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
 -ifneq ($(CONFIG_CMD_BMP)$(CONFIG_SPLASH_SCREEN),)
 -$(obj)lcd.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
 +# This option is not just y/n - it can have a numeric value
 +ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 +obj-y += aboot.o
 +obj-y += fb_mmc.o
  endif
  
 -#########################################################################
 +obj-$(CONFIG_CMD_BLOB) += cmd_blob.o
  
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 +# We always have this since drivers/ddr/fs/interactive.c needs it
 +obj-y += cli_simple.o
  
 -sinclude $(obj).depend
 +obj-y += cli.o
 +obj-y += cli_readline.o
 +obj-y += command.o
 +obj-y += s_record.o
 +obj-y += xyzModem.o
 +obj-y += cmd_disk.o
  
 -#########################################################################
 +CFLAGS_env_embedded.o := -Wa,--no-warn -DENV_CRC=$(shell tools/envcrc 2>/dev/null)
diff --combined common/cmd_bootce.c
index 0000000000000000000000000000000000000000,c30ed1feeaec843a0496e4977f732b47f59ec098..a95f163d479a2f92ce66dde8ad63ba25a5958048
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1040 +1,1038 @@@
 -#define UINT_MAX ~0UL
 -
+ /*
+  * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+  * based on: code from RedBoot (C) Uwe Steinkohl <US@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License as
+  * published by the Free Software Foundation; either version 2 of
+  * the License, or (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  * MA 02111-1307 USA
+  */
+ #include <common.h>
+ #include <command.h>
+ #include <net.h>
+ #include <wince.h>
+ #include <nand.h>
+ #include <malloc.h>
+ #include <asm/errno.h>
+ #include <jffs2/load_kernel.h>
+ DECLARE_GLOBAL_DATA_PTR;
+ #define WINCE_VRAM_BASE               0x80000000
+ #define CE_FIX_ADDRESS(a)     ((void *)((a) - WINCE_VRAM_BASE + CONFIG_SYS_SDRAM_BASE))
+ #ifndef INT_MAX
+ #define INT_MAX                       ((int)(~0U >> 1))
+ #endif
+ /* Bin image parse states */
+ #define CE_PS_RTI_ADDR                0
+ #define CE_PS_RTI_LEN         1
+ #define CE_PS_E_ADDR          2
+ #define CE_PS_E_LEN           3
+ #define CE_PS_E_CHKSUM                4
+ #define CE_PS_E_DATA          5
+ #define CE_MIN(a, b)          (((a) < (b)) ? (a) : (b))
+ #define CE_MAX(a, b)          (((a) > (b)) ? (a) : (b))
+ static ce_bin __attribute__ ((aligned (32))) g_bin;
+ static ce_net __attribute__ ((aligned (32))) g_net;
+ static IPaddr_t server_ip;
+ static void ce_init_bin(ce_bin *bin, unsigned char *dataBuffer)
+ {
+       memset(bin, 0, sizeof(*bin));
+       bin->data = dataBuffer;
+       bin->parseState = CE_PS_RTI_ADDR;
+       bin->parsePtr = (unsigned char *)bin;
+ }
+ static int ce_is_bin_image(void *image, int imglen)
+ {
+       if (imglen < CE_BIN_SIGN_LEN) {
+               return 0;
+       }
+       return memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
+ }
+ static const struct ce_magic {
+       char magic[8];
+       size_t size;
+       ce_std_driver_globals drv_glb;
+ } ce_magic_template = {
+       .magic = "KARO_CE6",
+       .size = sizeof(ce_std_driver_globals),
+       .drv_glb = {
+               .header = {
+                       .signature = STD_DRV_GLB_SIGNATURE,
+                       .oalVersion = 1,
+                       .bspVersion = 2,
+               },
+       },
+ };
+ #ifdef DEBUG
+ static void __attribute__((unused)) ce_dump_block(void *ptr, int length)
+ {
+       char *p = ptr;
+       int i;
+       int j;
+       for (i = 0; i < length; i++) {
+               if (!(i % 16)) {
+                       printf("\n%p: ", ptr + i);
+               }
+               printf("%02x ", p[i]);
+               if (!((i + 1) % 16)){
+                       printf("      ");
+                       for (j = i - 15; j <= i; j++){
+                               if((p[j] > 0x1f) && (p[j] < 0x7f)) {
+                                       printf("%c", p[j]);
+                               } else {
+                                       printf(".");
+                               }
+                       }
+               }
+       }
+       printf("\n");
+ }
+ #else
+ static inline void ce_dump_block(void *ptr, int length)
+ {
+ }
+ #endif
+ static void ce_setup_std_drv_globals(ce_std_driver_globals *std_drv_glb)
+ {
+       char *mtdparts = getenv("mtdparts");
+       size_t max_len = ALIGN((unsigned long)std_drv_glb, SZ_4K) -
+               (unsigned long)&std_drv_glb->mtdparts;
+       if (eth_get_dev()) {
+               memcpy(&std_drv_glb->kitl.mac, eth_get_dev()->enetaddr,
+                       sizeof(std_drv_glb->kitl.mac));
+       }
+       snprintf(std_drv_glb->deviceId, sizeof(std_drv_glb->deviceId),
+               "Triton%02X", eth_get_dev()->enetaddr[5]);
+       NetCopyIP(&std_drv_glb->kitl.ipAddress, &NetOurIP);
+       std_drv_glb->kitl.ipMask = getenv_IPaddr("netmask");
+       std_drv_glb->kitl.ipRoute = getenv_IPaddr("gatewayip");
+       if (mtdparts) {
+               strncpy(std_drv_glb->mtdparts, mtdparts, max_len);
+               std_drv_glb->mtdparts[max_len - 1] = '\0';
+       } else {
+               printf("Failed to get mtdparts environment variable\n");
+       }
+ }
+ static void ce_init_drv_globals(void)
+ {
+       struct ce_magic *ce_magic = (void *)CONFIG_SYS_SDRAM_BASE + 0x160;
+       ce_std_driver_globals *std_drv_glb = &ce_magic->drv_glb;
+       debug("Copying CE MAGIC from %p to %p..%p\n",
+               &ce_magic_template, ce_magic,
+               (void *)ce_magic + sizeof(*ce_magic) - 1);
+       memcpy(ce_magic, &ce_magic_template, sizeof(*ce_magic));
+       ce_setup_std_drv_globals(std_drv_glb);
+       ce_magic->size = sizeof(*std_drv_glb) +
+               strlen(std_drv_glb->mtdparts) + 1;
+       ce_dump_block(ce_magic, offsetof(struct ce_magic, drv_glb) +
+               ce_magic->size);
+ }
+ static void ce_prepare_run_bin(ce_bin *bin)
+ {
+       /* Clear os RAM area (if needed) */
+       if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
+               debug("cleaning memory from %p to %p\n",
+                       bin->eRamStart, bin->eRamStart + bin->eRamLen);
+               printf("Preparing clean boot ... ");
+               memset(bin->eRamStart, 0, bin->eRamLen);
+               printf("ok\n");
+       }
+       ce_init_drv_globals();
+       /*
+        * Make sure, all the above makes it into SDRAM because
+        * WinCE switches the cache & MMU off, obviously without
+        * flushing it first!
+        */
+       flush_dcache_all();
+ }
+ static int ce_lookup_ep_bin(ce_bin *bin)
+ {
+       ce_rom_hdr *header;
+       ce_toc_entry *tentry;
+       e32_rom *e32;
+       unsigned int i;
+       uint32_t *sig = (uint32_t *)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET);
+       debug("Looking for TOC signature at %p\n", sig);
+       /* Check image Table Of Contents (TOC) signature */
+       if (*sig != ROM_SIGNATURE) {
+               printf("Error: Did not find image TOC signature!\n");
+               printf("Expected %08x at address %p; found %08x instead\n",
+                       ROM_SIGNATURE, sig, *sig);
+               return 0;
+       }
+       /* Lookup entry point */
+       header = CE_FIX_ADDRESS(*(unsigned int *)(bin->rtiPhysAddr +
+                                               ROM_SIGNATURE_OFFSET +
+                                               sizeof(unsigned int)));
+       tentry = (ce_toc_entry *)(header + 1);
+       for (i = 0; i < header->nummods; i++) {
+               // Look for 'nk.exe' module
+               if (strcmp(CE_FIX_ADDRESS(tentry[i].fileName), "nk.exe") == 0) {
+                       // Save entry point and RAM addresses
+                       e32 = CE_FIX_ADDRESS(tentry[i].e32Offset);
+                       bin->eEntryPoint = CE_FIX_ADDRESS(tentry[i].loadOffset) +
+                               e32->e32_entryrva;
+                       bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
+                       bin->eRamLen = header->ramEnd - header->ramStart;
+                       return 1;
+               }
+       }
+       // Error: Did not find 'nk.exe' module
+       return 0;
+ }
+ static int ce_parse_bin(ce_bin *bin)
+ {
+       unsigned char *pbData = bin->data;
+       int len = bin->dataLen;
+       int copyLen;
+       debug("starting ce image parsing:\n\tbin->binLen: 0x%08X\n", bin->binLen);
+       if (len) {
+               if (bin->binLen == 0) {
+                       // Check for the .BIN signature first
+                       if (!ce_is_bin_image(pbData, len)) {
+                               printf("Error: Invalid or corrupted .BIN image!\n");
+                               return CE_PR_ERROR;
+                       }
+                       printf("Loading Windows CE .BIN image ...\n");
+                       // Skip signature
+                       len -= CE_BIN_SIGN_LEN;
+                       pbData += CE_BIN_SIGN_LEN;
+               }
+               while (len) {
+                       switch (bin->parseState) {
+                       case CE_PS_RTI_ADDR:
+                       case CE_PS_RTI_LEN:
+                       case CE_PS_E_ADDR:
+                       case CE_PS_E_LEN:
+                       case CE_PS_E_CHKSUM:
+                               copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, len);
+                               memcpy(&bin->parsePtr[bin->parseLen], pbData, copyLen);
+                               bin->parseLen += copyLen;
+                               len -= copyLen;
+                               pbData += copyLen;
+                               if (bin->parseLen == sizeof(unsigned int)) {
+                                       if (bin->parseState == CE_PS_RTI_ADDR)
+                                               bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
+                                       else if (bin->parseState == CE_PS_E_ADDR &&
+                                               bin->ePhysAddr)
+                                               bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
+                                       bin->parseState++;
+                                       bin->parseLen = 0;
+                                       bin->parsePtr += sizeof(unsigned int);
+                                       if (bin->parseState == CE_PS_E_DATA) {
+                                               if (bin->ePhysAddr) {
+                                                       bin->parsePtr = bin->ePhysAddr;
+                                                       bin->parseChkSum = 0;
+                                               } else {
+                                                       /* EOF */
+                                                       len = 0;
+                                                       bin->endOfBin = 1;
+                                               }
+                                       }
+                               }
+                               break;
+                       case CE_PS_E_DATA:
+                               debug("ePhysAddr=%p physlen=%08x parselen=%08x\n",
+                                       bin->ePhysAddr, bin->ePhysLen, bin->parseLen);
+                               if (bin->ePhysAddr) {
+                                       copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, len);
+                                       bin->parseLen += copyLen;
+                                       len -= copyLen;
+                                       while (copyLen--) {
+                                               bin->parseChkSum += *pbData;
+                                               *bin->parsePtr++ = *pbData++;
+                                       }
+                                       if (bin->parseLen == bin->ePhysLen) {
+                                               printf("Section [%02d]: address %p, size 0x%08X, checksum %s\n",
+                                                       bin->section,
+                                                       bin->ePhysAddr,
+                                                       bin->ePhysLen,
+                                                       (bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
+                                               if (bin->eChkSum != bin->parseChkSum) {
+                                                       printf("Error: Checksum error, corrupted .BIN file!\n");
+                                                       printf("checksum calculated: 0x%08x from file: 0x%08x\n",
+                                                               bin->parseChkSum, bin->eChkSum);
+                                                       bin->binLen = 0;
+                                                       return CE_PR_ERROR;
+                                               }
+                                               bin->section++;
+                                               bin->parseState = CE_PS_E_ADDR;
+                                               bin->parseLen = 0;
+                                               bin->parsePtr = (unsigned char *)&bin->ePhysAddr;
+                                       }
+                               } else {
+                                       bin->parseLen = 0;
+                                       bin->endOfBin = 1;
+                                       len = 0;
+                               }
+                               break;
+                       }
+               }
+       }
+       if (bin->endOfBin) {
+               if (!ce_lookup_ep_bin(bin)) {
+                       printf("Error: entry point not found!\n");
+                       bin->binLen = 0;
+                       return CE_PR_ERROR;
+               }
+               printf("Entry point: %p, address range: %p-%p\n",
+                       bin->eEntryPoint,
+                       bin->rtiPhysAddr,
+                       bin->rtiPhysAddr + bin->rtiPhysLen);
+               return CE_PR_EOF;
+       }
+       /* Need more data */
+       bin->binLen += bin->dataLen;
+       return CE_PR_MORE;
+ }
+ static int ce_bin_load(void *image, int imglen)
+ {
+       ce_init_bin(&g_bin, image);
+       g_bin.dataLen = imglen;
+       if (ce_parse_bin(&g_bin) == CE_PR_EOF) {
+               ce_prepare_run_bin(&g_bin);
+               return 1;
+       }
+       return 0;
+ }
+ static void ce_run_bin(void (*entry)(void))
+ {
+       printf("Launching Windows CE ...\n");
+ #ifdef TEST_LAUNCH
+ return;
+ #endif
+       entry();
+ }
+ static int do_bootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       void *addr;
+       size_t image_size;
+       if (argc > 1) {
+               if (strcmp(argv[1], "-i") == 0) {
+                       ce_init_drv_globals();
+                       return CMD_RET_SUCCESS;
+               }
+               addr = (void *)simple_strtoul(argv[1], NULL, 16);
+               image_size = INT_MAX;           /* actually we do not know the image size */
+       } else if (getenv("fileaddr") != NULL) {
+               addr = (void *)getenv_ulong("fileaddr", 16, 0);
+               image_size = getenv_ulong("filesize", 16, INT_MAX);
+       } else {
+               return CMD_RET_USAGE;
+       }
+       printf ("## Booting Windows CE Image from address %p ...\n", addr);
+       /* check if there is a valid windows CE image */
+       if (ce_is_bin_image(addr, image_size)) {
+               if (!ce_bin_load(addr, image_size)) {
+                       /* Ops! Corrupted .BIN image! */
+                       /* Handle error here ...      */
+                       printf("corrupted .BIN image !!!\n");
+                       return CMD_RET_FAILURE;
+               }
+               if (getenv_yesno("autostart") != 1) {
+                       /*
+                        * just use bootce to load the image to SDRAM;
+                        * Do not start it automatically.
+                        */
+                       setenv_addr("fileaddr", g_bin.eEntryPoint);
+                       return CMD_RET_SUCCESS;
+               }
+               ce_run_bin(g_bin.eEntryPoint);          /* start the image */
+       } else {
+               printf("Image does not seem to be a valid Windows CE image!\n");
+               return CMD_RET_FAILURE;
+       }
+       return CMD_RET_FAILURE; /* never reached - just to keep compiler happy */
+ }
+ U_BOOT_CMD(
+       bootce, 2, 0, do_bootce,
+       "Boot a Windows CE image from RAM",
+       "[addr]\n"
+       "\taddr\t\tboot image from address addr (default ${fileaddr})\n"
+       "or\n"
+       "\t-i\t\tinitialize the WinCE globals data structure (before loading a .nb0 image)"
+ );
+ #ifdef CONFIG_CMD_NAND
+ static int ce_nand_load(ce_bin *bin, loff_t *offset, void *buf, size_t max_len)
+ {
+       int ret;
+       size_t len = max_len;
+       nand_info_t *nand = &nand_info[0];
+       while (nand_block_isbad(nand, *offset & ~(max_len - 1))) {
+               printf("Skipping bad block 0x%08llx\n",
+                       *offset & ~(max_len - 1));
+               *offset += max_len;
+               if (*offset + max_len > nand->size)
+                       return -EINVAL;
+       }
+       ret = nand_read(nand, *offset, &len, buf);
+       if (ret < 0)
+               return ret;
+       bin->dataLen = len;
+       return len;
+ }
+ static int do_nbootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int ret;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+       loff_t offset;
+       char *end;
+       void *buffer;
+       size_t bufsize = nand_info[0].erasesize, len;
+       if (argc < 2 || argc > 3)
+               return CMD_RET_USAGE;
+       ret = mtdparts_init();
+       if (ret)
+               return CMD_RET_FAILURE;
+       offset = simple_strtoul(argv[1], &end, 16);
+       if (*end != '\0') {
+               ret = find_dev_and_part(argv[1], &dev, &part_num,
+                                       &part_info);
+               if (ret != 0) {
+                       printf("Partition '%s' not found\n", argv[1]);
+                       return CMD_RET_FAILURE;
+               }
+               offset = part_info->offset;
+               printf ("## Booting Windows CE Image from NAND partition %s at offset %08llx\n",
+                       argv[1], offset);
+       } else {
+               printf ("## Booting Windows CE Image from NAND offset %08llx\n",
+                       offset);
+       }
+       buffer = malloc(bufsize);
+       if (buffer == NULL) {
+               printf("Failed to allocate %u byte buffer\n", bufsize);
+               return CMD_RET_FAILURE;
+       }
+       ce_init_bin(&g_bin, buffer);
+       ret = ce_nand_load(&g_bin, &offset, buffer, bufsize);
+       if (ret < 0) {
+               printf("Failed to read NAND: %d\n", ret);
+               goto err;
+       }
+       len = ret;
+       /* check if there is a valid windows CE image header */
+       if (ce_is_bin_image(buffer, len)) {
+               do {
+                       ret = ce_parse_bin(&g_bin);
+                       switch (ret) {
+                       case CE_PR_MORE:
+                       {
+                               if (ctrlc()) {
+                                       printf("NBOOTCE - canceled by user\n");
+                                       goto err;
+                               }
+                               offset += len;
+                               len = ce_nand_load(&g_bin, &offset, buffer,
+                                               bufsize);
+                               if (len < 0) {
+                                       printf("Nand read error: %d\n", len);
+                                       ret = len;
+                                       goto err;
+                               }
+                       }
+                       break;
+                       case CE_PR_EOF:
+                               ce_prepare_run_bin(&g_bin);
+                               break;
+                       case CE_PR_ERROR:
+                               break;
+                       }
+               } while (ret == CE_PR_MORE);
+               free(buffer);
+               if (ret != CE_PR_EOF)
+                       return CMD_RET_FAILURE;
+               if (getenv_yesno("autostart") != 1) {
+                       /*
+                        * just use bootce to load the image to SDRAM;
+                        * Do not start it automatically.
+                        */
+                       setenv_addr("fileaddr", g_bin.eEntryPoint);
+                       return CMD_RET_SUCCESS;
+               }
+               ce_run_bin(g_bin.eEntryPoint);          /* start the image */
+       } else {
+               printf("Image does not seem to be a valid Windows CE image!\n");
+       }
+ err:
+       free(buffer);
+       return CMD_RET_FAILURE;
+ }
+ U_BOOT_CMD(
+       nbootce, 2, 0, do_nbootce,
+       "Boot a Windows CE image from NAND",
+       "off|partitition\n"
+       "\toff\t\t- flash offset (hex)\n"
+       "\tpartition\t- partition name"
+ );
+ #endif
+ static int ce_send_write_ack(ce_net *net)
+ {
+       int ret;
+       unsigned short wdata[2];
+       int retries = 0;
+       wdata[0] = htons(EDBG_CMD_WRITE_ACK);
+       wdata[1] = htons(net->blockNum);
+       net->dataLen = sizeof(wdata);
+       memcpy(net->data, wdata, net->dataLen);
+       do {
+               ret = bootme_send_frame(net->data, net->dataLen);
+               if (ret) {
+                       printf("Failed to send write ack %d; retries=%d\n",
+                               ret, retries);
+               }
+       } while (ret != 0 && retries-- > 0);
+       return ret;
+ }
+ static enum bootme_state ce_process_download(ce_net *net, ce_bin *bin)
+ {
+       int ret = net->state;
+       if (net->dataLen >= 4) {
+               unsigned short command;
+               unsigned short blknum;
+               memcpy(&command, net->data, sizeof(command));
+               command = ntohs(command);
+               debug("command found: 0x%04X\n", command);
+               if (net->state == BOOTME_DOWNLOAD) {
+                       unsigned short nxt = net->blockNum + 1;
+                       memcpy(&blknum, &net->data[2], sizeof(blknum));
+                       blknum = ntohs(blknum);
+                       if (blknum == nxt) {
+                               net->blockNum = blknum;
+                       } else {
+                               int rc = ce_send_write_ack(net);
+                               if (net->verbose)
+                                       printf("Dropping out of sequence packet with ID %d (expected %d)\n",
+                                               blknum, nxt);
+                               if (rc != 0)
+                                       return rc;
+                               return ret;
+                       }
+               }
+               switch (command) {
+               case EDBG_CMD_WRITE_REQ:
+                       if (net->state == BOOTME_INIT) {
+                               // Check file name for WRITE request
+                               // CE EShell uses "boot.bin" file name
+                               if (strncmp((char *)&net->data[2],
+                                               "boot.bin", 8) == 0) {
+                                       // Some diag output
+                                       if (net->verbose) {
+                                               printf("Locked Down download link, IP: %pI4\n",
+                                                       &NetServerIP);
+                                               printf("Sending BOOTME request [%d] to %pI4\n",
+                                                       net->seqNum, &NetServerIP);
+                                       }
+                                       // Lock down EShell download link
+                                       ret = BOOTME_DOWNLOAD;
+                               } else {
+                                       // Unknown link
+                                       printf("Unknown link\n");
+                               }
+                               if (ret == BOOTME_DOWNLOAD) {
+                                       int rc = ce_send_write_ack(net);
+                                       if (rc != 0)
+                                               return rc;
+                               }
+                       }
+                       break;
+               case EDBG_CMD_WRITE:
+                       /* Fixup data len */
+                       bin->data = &net->data[4];
+                       bin->dataLen = net->dataLen - 4;
+                       ret = ce_parse_bin(bin);
+                       if (ret != CE_PR_ERROR) {
+                               int rc = ce_send_write_ack(net);
+                               if (rc)
+                                       return rc;
+                               if (ret == CE_PR_EOF)
+                                       ret = BOOTME_DONE;
+                       } else {
+                               ret = BOOTME_ERROR;
+                       }
+                       break;
+               case EDBG_CMD_READ_REQ:
+                       printf("Ignoring EDBG_CMD_READ_REQ\n");
+                       /* Read requests are not supported
+                        * Do nothing ...
+                        */
+                       break;
+               case EDBG_CMD_ERROR:
+                       printf("Error: unknown error on the host side\n");
+                       bin->binLen = 0;
+                       ret = BOOTME_ERROR;
+                       break;
+               default:
+                       printf("unknown command 0x%04X\n", command);
+                       net->state = BOOTME_ERROR;
+               }
+       }
+       return ret;
+ }
+ static enum bootme_state ce_process_edbg(ce_net *net, ce_bin *bin)
+ {
+       enum bootme_state ret = net->state;
+       eth_dbg_hdr header;
+       if (net->dataLen < sizeof(header)) {
+               /* Bad packet */
+               printf("Invalid packet size %u\n", net->dataLen);
+               net->dataLen = 0;
+               return ret;
+       }
+       memcpy(&header, net->data, sizeof(header));
+       if (header.id != EDBG_ID) {
+               /* Bad packet */
+               printf("Bad EDBG ID %08x\n", header.id);
+               net->dataLen = 0;
+               return ret;
+       }
+       if (header.service != EDBG_SVC_ADMIN) {
+               /* Unknown service */
+               printf("Bad EDBG service %02x\n", header.service);
+               net->dataLen = 0;
+               return ret;
+       }
+       if (net->state == BOOTME_INIT) {
+               /* Some diag output */
+               if (net->verbose) {
+                       printf("Locked Down EDBG service link, IP: %pI4\n",
+                               &NetServerIP);
+               }
+               /* Lock down EDBG link */
+               net->state = BOOTME_DEBUG;
+       }
+       switch (header.cmd) {
+       case EDBG_CMD_JUMPIMG:
+               net->gotJumpingRequest = 1;
+               if (net->verbose) {
+                       printf("Received JUMPING command\n");
+               }
+               /* Just pass through and copy CONFIG structure */
+               ret = BOOTME_DONE;
+       case EDBG_CMD_OS_CONFIG:
+               /* Copy config structure */
+               memcpy(&bin->edbgConfig, &net->data[sizeof(header)],
+                       sizeof(edbg_os_config_data));
+               if (net->verbose) {
+                       printf("Received CONFIG command\n");
+                       if (bin->edbgConfig.flags & EDBG_FL_DBGMSG) {
+                               printf("--> Enabling DBGMSG service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.dbgMsgIPAddr,
+                                       ntohs(bin->edbgConfig.dbgMsgPort));
+                       }
+                       if (bin->edbgConfig.flags & EDBG_FL_PPSH) {
+                               printf("--> Enabling PPSH service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.ppshIPAddr,
+                                       ntohs(bin->edbgConfig.ppshPort));
+                       }
+                       if (bin->edbgConfig.flags & EDBG_FL_KDBG) {
+                               printf("--> Enabling KDBG service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.kdbgIPAddr,
+                                       ntohs(bin->edbgConfig.kdbgPort));
+                       }
+                       if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
+                               printf("--> Force clean boot\n");
+                       }
+               }
+               break;
+       default:
+               if (net->verbose) {
+                       printf("Received unknown command: %08X\n", header.cmd);
+               }
+               return BOOTME_ERROR;
+       }
+       /* Respond with ack */
+       header.flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
+       memcpy(net->data, &header, sizeof(header));
+       net->dataLen = EDBG_DATA_OFFSET;
+       int retries = 10;
+       int rc;
+       do {
+               rc = bootme_send_frame(net->data, net->dataLen);
+               if (rc != 0) {
+                       printf("Failed to send ACK: %d\n", rc);
+               }
+       } while (rc && retries-- > 0);
+       return rc ?: ret;
+ }
+ static enum bootme_state ce_edbg_handler(const void *buf, size_t len)
+ {
+       if (len == 0)
+               return BOOTME_DONE;
+       g_net.data = (void *)buf;
+       g_net.dataLen = len;
+       return ce_process_edbg(&g_net, &g_bin);
+ }
+ static void ce_init_edbg_link(ce_net *net)
+ {
+       /* Initialize EDBG link for commands */
+       net->state = BOOTME_INIT;
+ }
+ static enum bootme_state ce_download_handler(const void *buf, size_t len)
+ {
+       g_net.data = (void *)buf;
+       g_net.dataLen = len;
+       g_net.state = ce_process_download(&g_net, &g_bin);
+       return g_net.state;
+ }
+ static int ce_send_bootme(ce_net *net)
+ {
+       eth_dbg_hdr *header;
+       edbg_bootme_data *data;
+       unsigned char txbuf[PKTSIZE_ALIGN];
+ #ifdef DEBUG
+       int     i;
+       unsigned char   *pkt;
+ #endif
+       /* Fill out BOOTME packet */
+       net->data = txbuf;
+       memset(net->data, 0, PKTSIZE);
+       header = (eth_dbg_hdr *)net->data;
+       data = (edbg_bootme_data *)header->data;
+       header->id = EDBG_ID;
+       header->service = EDBG_SVC_ADMIN;
+       header->flags = EDBG_FL_FROM_DEV;
+       header->seqNum = net->seqNum++;
+       header->cmd = EDBG_CMD_BOOTME;
+       data->versionMajor = 0;
+       data->versionMinor = 0;
+       data->cpuId = EDBG_CPU_TYPE_ARM;
+       data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
+       data->bootFlags = 0;
+       data->downloadPort = 0;
+       data->svcPort = 0;
+       /* MAC address from environment*/
+       if (!eth_getenv_enetaddr("ethaddr", data->macAddr)) {
+               printf("'ethaddr' is not set or invalid\n");
+               memset(data->macAddr, 0, sizeof(data->macAddr));
+       }
+       /* IP address from active config */
+       NetCopyIP(&data->ipAddr, &NetOurIP);
+       // Device name string (NULL terminated). Should include
+       // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
+       // We will use lower MAC address segment to create device name
+       // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
+       strncpy(data->platformId, "Triton", sizeof(data->platformId));
+       snprintf(data->deviceName, sizeof(data->deviceName), "%s%02X",
+               data->platformId, data->macAddr[5]);
+ #ifdef DEBUG
+       printf("header->id: %08X\n", header->id);
+       printf("header->service: %08X\n", header->service);
+       printf("header->flags: %08X\n", header->flags);
+       printf("header->seqNum: %08X\n", header->seqNum);
+       printf("header->cmd: %08X\n\n", header->cmd);
+       printf("data->versionMajor: %08X\n", data->versionMajor);
+       printf("data->versionMinor: %08X\n", data->versionMinor);
+       printf("data->cpuId: %08X\n", data->cpuId);
+       printf("data->bootmeVer: %08X\n", data->bootmeVer);
+       printf("data->bootFlags: %08X\n", data->bootFlags);
+       printf("data->svcPort: %08X\n\n", ntohs(data->svcPort));
+       printf("data->macAddr: %pM\n", data->macAddr);
+       printf("data->ipAddr: %pI4\n", &data->ipAddr);
+       printf("data->platformId: %s\n", data->platformId);
+       printf("data->deviceName: %s\n", data->deviceName);
+ #endif
+       // Some diag output ...
+       if (net->verbose) {
+               printf("Sending BOOTME request [%d] to %pI4\n", net->seqNum,
+                       &server_ip);
+       }
+       net->dataLen = BOOTME_PKT_SIZE;
+ //    net->status = CE_PR_MORE;
+       net->state = BOOTME_INIT;
+ #ifdef DEBUG
+       debug("Start of buffer:      %p\n", net->data);
+       debug("Start of ethernet buffer:   %p\n", net->data);
+       debug("Start of CE header:         %p\n", header);
+       debug("Start of CE data:           %p\n", data);
+       pkt = net->data;
+       debug("packet to send (ceconnect): \n");
+       for (i = 0; i < net->dataLen; i++) {
+               debug("0x%02X ", pkt[i]);
+               if (!((i + 1) % 16))
+                       debug("\n");
+       }
+       debug("\n");
+ #endif
+       return BootMeRequest(server_ip, net->data, net->dataLen, 1);
+ }
+ static inline int ce_init_download_link(ce_net *net, ce_bin *bin, int verbose)
+ {
+       if (!eth_get_dev()) {
+               printf("No network interface available\n");
+               return -ENODEV;
+       }
+       printf("Using device '%s'\n", eth_get_name());
+       /* Initialize EDBG link for download */
+       memset(net, 0, sizeof(*net));
+       net->verbose = verbose;
+       /* buffer will be dynamically assigned in ce_download_handler() */
+       ce_init_bin(bin, NULL);
+       return 0;
+ }
 -                                      printf("Timeout value %lu out of range (max.: %lu)\n",
+ static inline int ce_download_file(ce_net *net, ulong timeout)
+ {
+       ulong start = get_timer_masked();
+       while (net->state == BOOTME_INIT) {
+               int ret;
+               if (timeout && get_timer(start) > timeout) {
+                       printf("CELOAD - Canceled, timeout\n");
+                       return 1;
+               }
+               if (ctrlc()) {
+                       printf("CELOAD - canceled by user\n");
+                       return 1;
+               }
+               if (ce_send_bootme(&g_net)) {
+                       printf("CELOAD - error while sending BOOTME request\n");
+                       return 1;
+               }
+               if (net->verbose) {
+                       if (timeout) {
+                               printf("Waiting for connection, timeout %lu sec\n",
+                                       DIV_ROUND_UP(timeout - get_timer(start),
+                                               CONFIG_SYS_HZ));
+                       } else {
+                               printf("Waiting for connection, enter ^C to abort\n");
+                       }
+               }
+               ret = BootMeDownload(ce_download_handler);
+               if (ret == BOOTME_ERROR) {
+                       printf("CELOAD - aborted\n");
+                       return 1;
+               }
+       }
+       return 0;
+ }
+ static void ce_disconnect(void)
+ {
+       net_set_udp_handler(NULL);
+       eth_halt();
+ }
+ static int do_ceconnect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+ {
+       int verbose = 0;
+       ulong timeout = 0;
+       int ret = 1;
+       int i;
+       server_ip = 0;
+       for (i = 1; i < argc; i++){
+               if (*argv[i] != '-')
+                       break;
+               if (argv[i][1] == 'v') {
+                       verbose = 1;
+               } else if (argv[i][1] == 't') {
+                       i++;
+                       if (argc > i) {
+                               timeout = simple_strtoul(argv[i],
+                                                       NULL, 0);
+                               if (timeout >= UINT_MAX / CONFIG_SYS_HZ) {
++                                      printf("Timeout value %lu out of range (max.: %u)\n",
+                                               timeout, UINT_MAX / CONFIG_SYS_HZ - 1);
+                                       return CMD_RET_USAGE;
+                               }
+                               timeout *= CONFIG_SYS_HZ;
+                       } else {
+                               printf("Option requires an argument - t\n");
+                               return CMD_RET_USAGE;
+                       }
+               } else if (argv[i][1] == 'h') {
+                       i++;
+                       if (argc > i) {
+                               server_ip = string_to_ip(argv[i]);
+                               printf("Using server %pI4\n", &server_ip);
+                       } else {
+                               printf("Option requires an argument - h\n");
+                               return CMD_RET_USAGE;
+                       }
+               }
+       }
+       if (ce_init_download_link(&g_net, &g_bin, verbose) != 0)
+               goto err;
+       if (ce_download_file(&g_net, timeout))
+               goto err;
+       if (g_bin.binLen) {
+               // Try to receive edbg commands from host
+               ce_init_edbg_link(&g_net);
+               if (verbose)
+                       printf("Waiting for EDBG commands ...\n");
+               ret = BootMeDebugStart(ce_edbg_handler);
+               if (ret != BOOTME_DONE)
+                       goto err;
+               // Prepare WinCE image for execution
+               ce_prepare_run_bin(&g_bin);
+               // Launch WinCE, if necessary
+               if (g_net.gotJumpingRequest)
+                       ce_run_bin(g_bin.eEntryPoint);
+       }
+       ret = 0;
+ err:
+       ce_disconnect();
+       return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+ }
+ U_BOOT_CMD(
+       ceconnect, 6, 1, do_ceconnect,
+       "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
+       "[-v] [-t <timeout>] [-h host]\n"
+       "  -v            - verbose operation\n"
+       "  -t <timeout>  - max wait time (#sec) for the connection\n"
+       "  -h <host>     - send BOOTME requests to <host> (default: broadcast address 255.255.255.255)"
+ );
diff --combined common/cmd_gpt.c
index e38422d792eec2784102bccadea93b5b522c8666,d8c6b431586e1887e66cb63a548e2ba8cd17b46a..446da2c97009a8ab682ad5726204a7d785dfa846
@@@ -11,6 -11,7 +11,6 @@@
  #include <common.h>
  #include <malloc.h>
  #include <command.h>
 -#include <mmc.h>
  #include <part_efi.h>
  #include <exports.h>
  #include <linux/ctype.h>
   *
   * @return - zero on successful expand and env is set
   */
 -static char extract_env(const char *str, char **env)
 +static int extract_env(const char *str, char **env)
  {
 +      int ret = -1;
        char *e, *s;
 +#ifdef CONFIG_RANDOM_UUID
 +      char uuid_str[UUID_STR_LEN + 1];
 +#endif
  
        if (!str || strlen(str) < 4)
                return -1;
  
 -      if ((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')) {
 -              s = strdup(str);
 -              if (s == NULL)
 -                      return -1;
 -              memset(s + strlen(s) - 1, '\0', 1);
 -              memmove(s, s + 2, strlen(s) - 1);
 +      if (!((strncmp(str, "${", 2) == 0) && (str[strlen(str) - 1] == '}')))
 +              return -1;
 +
 +      s = strdup(str);
 +      if (s == NULL)
 +              return -1;
 +
 +      memset(s + strlen(s) - 1, '\0', 1);
 +      memmove(s, s + 2, strlen(s) - 1);
 +
 +      e = getenv(s);
 +      if (e == NULL) {
 +#ifdef CONFIG_RANDOM_UUID
 +              debug("%s unset. ", str);
 +              gen_rand_uuid_str(uuid_str, UUID_STR_FORMAT_STD);
 +              setenv(s, uuid_str);
 +
                e = getenv(s);
 -              free(s);
 -              if (e == NULL) {
 -                      printf("Environmental '%s' not set\n", str);
 -                      return -1; /* env not set */
 +              if (e) {
 +                      debug("Set to random.\n");
 +                      ret = 0;
 +              } else {
 +                      debug("Can't get random UUID.\n");
                }
 -              *env = e;
 -              return 0;
 +#else
 +              debug("%s unset.\n", str);
 +#endif
 +      } else {
 +              debug("%s get from environment.\n", str);
 +              ret = 0;
        }
  
 -      return -1;
 +      *env = e;
 +      free(s);
 +
 +      return ret;
  }
  
  /**
@@@ -141,10 -119,11 +141,11 @@@ static int set_gpt_info(block_dev_desc_
        char *val, *p;
        int p_count;
        disk_partition_t *parts;
+       char *guid_str;
        int errno = 0;
        uint64_t size_ll, start_ll;
  
 -      debug("%s: MMC lba num: 0x%x %d\n", __func__,
 +      debug("%s:  lba num: 0x%x %d\n", __func__,
              (unsigned int)dev_desc->lba, (unsigned int)dev_desc->lba);
  
        if (str_part == NULL)
        tok = strsep(&s, ";");
        val = extract_val(tok, "uuid_disk");
        if (!val) {
-               free(str);
-               return -2;
+               errno = -2;
+               goto free_str;
        }
-       if (extract_env(val, &p))
-               p = val;
-       *str_disk_guid = strdup(p);
+       if (extract_env(val, &p) == 0)
+               guid_str = strdup(p);
+       else
+               guid_str = strdup(val);
        free(val);
  
-       if (strlen(s) == 0)
-               return -3;
+       if (strlen(s) == 0) {
+               errno = -3;
+               goto free_guid;
+       }
  
        i = strlen(s) - 1;
        if (s[i] == ';')
        /* allocate memory for partitions */
        parts = calloc(sizeof(disk_partition_t), p_count);
  
 -      /* retrive partions data from string */
 +      /* retrieve partitions data from string */
        for (i = 0; i < p_count; i++) {
                tok = strsep(&s, ";");
  
                }
        }
  
+       *str_disk_guid = guid_str;
        *parts_count = p_count;
        *partitions = parts;
        free(str);
  
        return 0;
  err:
-       free(str);
-       free(*str_disk_guid);
        free(parts);
+ free_guid:
+       free(guid_str);
+ free_str:
+       free(str);
  
+       *str_disk_guid = NULL;
+       *parts_count = 0;
+       *partitions = NULL;
        return errno;
  }
  
 -static int gpt_mmc_default(int dev, const char *str_part)
 +static int gpt_default(block_dev_desc_t *blk_dev_desc, const char *str_part)
  {
        int ret;
        char *str_disk_guid;
        u8 part_count = 0;
        disk_partition_t *partitions = NULL;
  
 -      struct mmc *mmc = find_mmc_device(dev);
 -
 -      if (mmc == NULL) {
 -              printf("%s: mmc dev %d NOT available\n", __func__, dev);
 -              return CMD_RET_FAILURE;
 -      }
 -
        if (!str_part)
                return -1;
  
        /* fill partitions */
 -      ret = set_gpt_info(&mmc->block_dev, str_part,
 +      ret = set_gpt_info(blk_dev_desc, str_part,
                        &str_disk_guid, &partitions, &part_count);
        if (ret) {
                if (ret == -1)
        }
  
        /* save partitions layout to disk */
 -      gpt_restore(&mmc->block_dev, str_disk_guid, partitions, part_count);
 +      gpt_restore(blk_dev_desc, str_disk_guid, partitions, part_count);
        free(str_disk_guid);
        free(partitions);
  
@@@ -302,35 -299,26 +314,35 @@@ static int do_gpt(cmd_tbl_t *cmdtp, in
  {
        int ret = CMD_RET_SUCCESS;
        int dev = 0;
 -      char *pstr;
 +      char *ep;
 +      block_dev_desc_t *blk_dev_desc;
  
        if (argc < 5)
                return CMD_RET_USAGE;
  
        /* command: 'write' */
        if ((strcmp(argv[1], "write") == 0) && (argc == 5)) {
 -              /* device: 'mmc' */
 -              if (strcmp(argv[2], "mmc") == 0) {
 -                      /* check if 'dev' is a number */
 -                      for (pstr = argv[3]; *pstr != '\0'; pstr++)
 -                              if (!isdigit(*pstr)) {
 -                                      printf("'%s' is not a number\n",
 -                                              argv[3]);
 -                                      return CMD_RET_USAGE;
 -                              }
 -                      dev = (int)simple_strtoul(argv[3], NULL, 10);
 -                      /* write to mmc */
 -                      if (gpt_mmc_default(dev, argv[4]))
 -                              return CMD_RET_FAILURE;
 +              dev = (int)simple_strtoul(argv[3], &ep, 10);
 +              if (!ep || ep[0] != '\0') {
 +                      printf("'%s' is not a number\n", argv[3]);
 +                      return CMD_RET_USAGE;
 +              }
 +              blk_dev_desc = get_dev(argv[2], dev);
 +              if (!blk_dev_desc) {
 +                      printf("%s: %s dev %d NOT available\n",
 +                             __func__, argv[2], dev);
 +                      return CMD_RET_FAILURE;
 +              }
 +
 +              puts("Writing GPT: ");
 +
 +              ret = gpt_default(blk_dev_desc, argv[4]);
 +              if (!ret) {
 +                      puts("success!\n");
 +                      return CMD_RET_SUCCESS;
 +              } else {
 +                      puts("error!\n");
 +                      return CMD_RET_FAILURE;
                }
        } else {
                return CMD_RET_USAGE;
  
  U_BOOT_CMD(gpt, CONFIG_SYS_MAXARGS, 1, do_gpt,
        "GUID Partition Table",
 -      "<command> <interface> <dev> <partions_list>\n"
 +      "<command> <interface> <dev> <partitions_list>\n"
        " - GUID partition table restoration\n"
        " Restore GPT information on a device connected\n"
        " to interface\n"
diff --combined common/cmd_mmc.c
index 96478e45c14039cd88a1a59427d0ec7f1a44d07e,c9c1a19791956e2385f837888ef03dddf5b1cb8f..4565a216682e4a02273654615bbbd81e22ddbd82
@@@ -32,7 -32,7 +32,7 @@@ int do_mmc (cmd_tbl_t *cmdtp, int flag
  
                if (mmc_legacy_init(dev) != 0) {
                        puts("No MMC card found\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
  
                curr_device = dev;
                if (argc == 2) {
                        if (curr_device < 0) {
                                puts("No MMC device available\n");
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                } else if (argc == 3) {
                        dev = (int)simple_strtoul(argv[2], NULL, 10);
  
  #ifdef CONFIG_SYS_MMC_SET_DEV
                        if (mmc_set_dev(dev) != 0)
-                               return 1;
+                               return CMD_RET_FAILURE;
  #endif
                        curr_device = dev;
                } else {
@@@ -60,7 -60,7 +60,7 @@@
                return CMD_RET_USAGE;
        }
  
-       return 0;
+       return CMD_RET_SUCCESS;
  }
  
  U_BOOT_CMD(
  );
  #else /* !CONFIG_GENERIC_MMC */
  
 -enum mmc_state {
 -      MMC_INVALID,
 -      MMC_READ,
 -      MMC_WRITE,
 -      MMC_ERASE,
 -};
  static void print_mmcinfo(struct mmc *mmc)
  {
 -      printf("Device: %s\n", mmc->name);
 +      printf("Device: %s\n", mmc->cfg->name);
        printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
        printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
        printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff,
        puts("Capacity: ");
        print_size(mmc->capacity, "\n");
  
 -      printf("Bus Width: %d-bit\n", mmc->bus_width);
 +      printf("Bus Width: %d-bit%s\n", mmc->bus_width,
 +                      mmc->ddr_mode ? " DDR" : "");
 +}
 +static struct mmc *init_mmc_device(int dev, bool force_init)
 +{
 +      struct mmc *mmc;
 +      mmc = find_mmc_device(dev);
 +      if (!mmc) {
 +              printf("no mmc device at slot %x\n", dev);
 +              return NULL;
 +      }
 +      if (force_init)
 +              mmc->has_init = 0;
 +      if (mmc_init(mmc))
 +              return NULL;
 +      return mmc;
  }
 -
  static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  {
        struct mmc *mmc;
                        curr_device = 0;
                else {
                        puts("No MMC device available\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
        }
  
 -      mmc = find_mmc_device(curr_device);
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -      if (mmc) {
 -              mmc_init(mmc);
 +      print_mmcinfo(mmc);
 +      return CMD_RET_SUCCESS;
 +}
  
 -              print_mmcinfo(mmc);
 -              return CMD_RET_SUCCESS;
 -      } else {
 -              printf("no mmc device at slot %x\n", curr_device);
 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
 +static int confirm_key_prog(void)
 +{
 +      puts("Warning: Programming authentication key can be done only once !\n"
 +           "         Use this command only if you are sure of what you are doing,\n"
 +           "Really perform the key programming? <y/N> ");
 +      if (confirm_yesno())
 +              return 1;
 +
 +      puts("Authentication key programming aborted\n");
 +      return 0;
 +}
 +static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
 +                        int argc, char * const argv[])
 +{
 +      void *key_addr;
 +      struct mmc *mmc = find_mmc_device(curr_device);
 +
 +      if (argc != 2)
 +              return CMD_RET_USAGE;
 +
 +      key_addr = (void *)simple_strtoul(argv[1], NULL, 16);
 +      if (!confirm_key_prog())
 +              return CMD_RET_FAILURE;
 +      if (mmc_rpmb_set_key(mmc, key_addr)) {
 +              printf("ERROR - Key already programmed ?\n");
                return CMD_RET_FAILURE;
        }
 +      return CMD_RET_SUCCESS;
  }
 +static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
 +                         int argc, char * const argv[])
 +{
 +      u16 blk, cnt;
 +      void *addr;
 +      int n;
 +      void *key_addr = NULL;
 +      struct mmc *mmc = find_mmc_device(curr_device);
  
 -U_BOOT_CMD(
 -      mmcinfo, 1, 0, do_mmcinfo,
 -      "display MMC info",
 -      "- display info of the current MMC device"
 -);
 +      if (argc < 4)
 +              return CMD_RET_USAGE;
  
 -#ifdef CONFIG_SUPPORT_EMMC_BOOT
 -static int boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
 +      addr = (void *)simple_strtoul(argv[1], NULL, 16);
 +      blk = simple_strtoul(argv[2], NULL, 16);
 +      cnt = simple_strtoul(argv[3], NULL, 16);
 +
 +      if (argc == 5)
 +              key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
 +
 +      printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ",
 +             curr_device, blk, cnt);
 +      n =  mmc_rpmb_read(mmc, addr, blk, cnt, key_addr);
 +
 +      printf("%d RPMB blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 +      if (n != cnt)
 +              return CMD_RET_FAILURE;
 +      return CMD_RET_SUCCESS;
 +}
 +static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
 +                          int argc, char * const argv[])
  {
 -      int err;
 -      err = mmc_boot_part_access(mmc, ack, part_num, access);
 +      u16 blk, cnt;
 +      void *addr;
 +      int n;
 +      void *key_addr;
 +      struct mmc *mmc = find_mmc_device(curr_device);
 +
 +      if (argc != 5)
 +              return CMD_RET_USAGE;
  
 -      if ((err == 0) && (access != 0)) {
 -              printf("Notice!\n");
 +      addr = (void *)simple_strtoul(argv[1], NULL, 16);
 +      blk = simple_strtoul(argv[2], NULL, 16);
 +      cnt = simple_strtoul(argv[3], NULL, 16);
 +      key_addr = (void *)simple_strtoul(argv[4], NULL, 16);
  
 -              printf("You must close EMMC boot Partition after all images are written\n");
 -              printf("EMMC boot partition has continuity at image writing time.\n");
 -              printf("So, do not close the boot partition before all images are written.\n");
 -              return CMD_RET_SUCCESS;
 -      } else if ((err == 0) && (access == 0))
 +      printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ",
 +             curr_device, blk, cnt);
 +      n =  mmc_rpmb_write(mmc, addr, blk, cnt, key_addr);
 +
 +      printf("%d RPMB blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 +      if (n != cnt)
 +              return CMD_RET_FAILURE;
 +      return CMD_RET_SUCCESS;
 +}
 +static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag,
 +                            int argc, char * const argv[])
 +{
 +      unsigned long counter;
 +      struct mmc *mmc = find_mmc_device(curr_device);
 +
 +      if (mmc_rpmb_get_counter(mmc, &counter))
 +              return CMD_RET_FAILURE;
 +      printf("RPMB Write counter= %lx\n", counter);
 +      return CMD_RET_SUCCESS;
 +}
 +
 +static cmd_tbl_t cmd_rpmb[] = {
 +      U_BOOT_CMD_MKENT(key, 2, 0, do_mmcrpmb_key, "", ""),
 +      U_BOOT_CMD_MKENT(read, 5, 1, do_mmcrpmb_read, "", ""),
 +      U_BOOT_CMD_MKENT(write, 5, 0, do_mmcrpmb_write, "", ""),
 +      U_BOOT_CMD_MKENT(counter, 1, 1, do_mmcrpmb_counter, "", ""),
 +};
 +
 +static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
 +                    int argc, char * const argv[])
 +{
 +      cmd_tbl_t *cp;
 +      struct mmc *mmc;
 +      char original_part;
 +      int ret;
 +
 +      cp = find_cmd_tbl(argv[1], cmd_rpmb, ARRAY_SIZE(cmd_rpmb));
 +
 +      /* Drop the rpmb subcommand */
 +      argc--;
 +      argv++;
 +
 +      if (cp == NULL || argc > cp->maxargs)
 +              return CMD_RET_USAGE;
 +      if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
                return CMD_RET_SUCCESS;
 -      else if ((err != 0) && (access != 0)) {
 -              printf("EMMC boot partition-%d OPEN Failed.\n", part_num);
 +
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
                return CMD_RET_FAILURE;
 -      } else {
 -              printf("EMMC boot partition-%d CLOSE Failed.\n", part_num);
 +
 +      if (!(mmc->version & MMC_VERSION_MMC)) {
 +              printf("It is not a EMMC device\n");
 +              return CMD_RET_FAILURE;
 +      }
 +      if (mmc->version < MMC_VERSION_4_41) {
 +              printf("RPMB not supported before version 4.41\n");
                return CMD_RET_FAILURE;
        }
 +      /* Switch to the RPMB partition */
 +      original_part = mmc->part_num;
 +      if (mmc->part_num != MMC_PART_RPMB) {
 +              if (mmc_switch_part(curr_device, MMC_PART_RPMB) != 0)
 +                      return CMD_RET_FAILURE;
 +              mmc->part_num = MMC_PART_RPMB;
 +      }
 +      ret = cp->cmd(cmdtp, flag, argc, argv);
 +
 +      /* Return to original partition */
 +      if (mmc->part_num != original_part) {
 +              if (mmc_switch_part(curr_device, original_part) != 0)
 +                      return CMD_RET_FAILURE;
 +              mmc->part_num = original_part;
 +      }
 +      return ret;
  }
  #endif
  
 -static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 +static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
 +                     int argc, char * const argv[])
  {
 -      enum mmc_state state;
 +      struct mmc *mmc;
 +      u32 blk, cnt, n;
 +      void *addr;
  
 -      if (argc < 2)
 +      if (argc != 4)
                return CMD_RET_USAGE;
  
 -      if (curr_device < 0) {
 -              if (get_mmc_num() > 0)
 -                      curr_device = 0;
 -              else {
 -                      puts("No MMC device available\n");
 -                      return CMD_RET_FAILURE;
 -              }
 +      addr = (void *)simple_strtoul(argv[1], NULL, 16);
 +      blk = simple_strtoul(argv[2], NULL, 16);
 +      cnt = simple_strtoul(argv[3], NULL, 16);
 +
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
 +
 +      printf("\nMMC read: dev # %d, block # %d, count %d ... ",
 +             curr_device, blk, cnt);
 +
 +      n = mmc->block_dev.block_read(curr_device, blk, cnt, addr);
 +      /* flush cache after read */
 +      flush_cache((ulong)addr, cnt * 512); /* FIXME */
 +      printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
 +
 +      return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 +}
 +static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
 +                      int argc, char * const argv[])
 +{
 +      struct mmc *mmc;
 +      u32 blk, cnt, n;
 +      void *addr;
 +
 +      if (argc != 4)
 +              return CMD_RET_USAGE;
 +
 +      addr = (void *)simple_strtoul(argv[1], NULL, 16);
 +      blk = simple_strtoul(argv[2], NULL, 16);
 +      cnt = simple_strtoul(argv[3], NULL, 16);
 +
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
 +
 +      printf("\nMMC write: dev # %d, block # %d, count %d ... ",
 +             curr_device, blk, cnt);
 +
 +      if (mmc_getwp(mmc) == 1) {
 +              printf("Error: card is write protected!\n");
 +              return CMD_RET_FAILURE;
        }
 +      n = mmc->block_dev.block_write(curr_device, blk, cnt, addr);
 +      printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
  
 -      if (strcmp(argv[1], "rescan") == 0) {
 -              struct mmc *mmc;
 +      return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 +}
 +static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
 +                      int argc, char * const argv[])
 +{
 +      struct mmc *mmc;
 +      u32 blk, cnt, n;
  
 -              if (argc != 2)
 -                      return CMD_RET_USAGE;
 +      if (argc != 3)
 +              return CMD_RET_USAGE;
  
 -              mmc = find_mmc_device(curr_device);
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", curr_device);
 -                      return CMD_RET_FAILURE;
 -              }
 +      blk = simple_strtoul(argv[1], NULL, 16);
 +      cnt = simple_strtoul(argv[2], NULL, 16);
  
 -              mmc->has_init = 0;
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -              if (mmc_init(mmc))
 -                      return CMD_RET_FAILURE;
 -              else
 -                      return CMD_RET_SUCCESS;
 -      } else if (strncmp(argv[1], "part", 4) == 0) {
 -              block_dev_desc_t *mmc_dev;
 -              struct mmc *mmc;
 +      printf("\nMMC erase: dev # %d, block # %d, count %d ... ",
 +             curr_device, blk, cnt);
  
 -              if (argc != 2)
 -                      return CMD_RET_USAGE;
 +      if (mmc_getwp(mmc) == 1) {
 +              printf("Error: card is write protected!\n");
 +              return CMD_RET_FAILURE;
 +      }
 +      n = mmc->block_dev.block_erase(curr_device, blk, cnt);
 +      printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR");
  
 -              mmc = find_mmc_device(curr_device);
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", curr_device);
 -                      return CMD_RET_FAILURE;
 -              }
 -              mmc_init(mmc);
 -              mmc_dev = mmc_get_dev(curr_device);
 -              if (mmc_dev != NULL &&
 -                              mmc_dev->type != DEV_TYPE_UNKNOWN) {
 -                      print_part(mmc_dev);
 -                      return CMD_RET_SUCCESS;
 -              }
 +      return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 +}
 +static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
 +                       int argc, char * const argv[])
 +{
 +      struct mmc *mmc;
  
 -              puts("get mmc type error!\n");
 +      mmc = init_mmc_device(curr_device, true);
 +      if (!mmc)
                return CMD_RET_FAILURE;
 -      } else if (strcmp(argv[1], "list") == 0) {
 -              if (argc != 2)
 -                      return CMD_RET_USAGE;
 -              print_mmc_devices('\n');
 +
 +      return CMD_RET_SUCCESS;
 +}
 +static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
 +                     int argc, char * const argv[])
 +{
 +      block_dev_desc_t *mmc_dev;
 +      struct mmc *mmc;
 +
 +      mmc = init_mmc_device(curr_device, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
 +
 +      mmc_dev = mmc_get_dev(curr_device);
 +      if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
 +              print_part(mmc_dev);
                return CMD_RET_SUCCESS;
 -      } else if (strcmp(argv[1], "dev") == 0) {
 -              int dev, part = -1;
 -              struct mmc *mmc;
 -
 -              if (argc == 2)
 -                      dev = curr_device;
 -              else if (argc == 3)
 -                      dev = simple_strtoul(argv[2], NULL, 10);
 -              else if (argc == 4) {
 -                      dev = (int)simple_strtoul(argv[2], NULL, 10);
 -                      part = (int)simple_strtoul(argv[3], NULL, 10);
 -                      if (part > PART_ACCESS_MASK) {
 -                              printf("#part_num shouldn't be larger"
 -                                      " than %d\n", PART_ACCESS_MASK);
 -                              return CMD_RET_FAILURE;
 -                      }
 -              } else
 -                      return CMD_RET_USAGE;
 +      }
  
 -              mmc = find_mmc_device(dev);
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", dev);
 +      puts("get mmc type error!\n");
 +      return CMD_RET_FAILURE;
 +}
 +static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
 +                    int argc, char * const argv[])
 +{
 +      int dev, part = 0, ret;
 +      struct mmc *mmc;
 +
 +      if (argc == 1) {
 +              dev = curr_device;
 +      } else if (argc == 2) {
 +              dev = simple_strtoul(argv[1], NULL, 10);
 +      } else if (argc == 3) {
 +              dev = (int)simple_strtoul(argv[1], NULL, 10);
 +              part = (int)simple_strtoul(argv[2], NULL, 10);
 +              if (part > PART_ACCESS_MASK) {
 +                      printf("#part_num shouldn't be larger than %d\n",
 +                             PART_ACCESS_MASK);
                        return CMD_RET_FAILURE;
                }
 +      } else {
 +              return CMD_RET_USAGE;
 +      }
  
 -              mmc_init(mmc);
 -              if (part != -1) {
 -                      int ret;
 -                      if (mmc->part_config == MMCPART_NOAVAILABLE) {
 -                              printf("Card doesn't support part_switch\n");
 -                              return CMD_RET_FAILURE;
 -                      }
 +      mmc = init_mmc_device(dev, true);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -                      if (part != mmc->part_num) {
 -                              ret = mmc_switch_part(dev, part);
 -                              if (!ret)
 -                                      mmc->part_num = part;
 +      ret = mmc_select_hwpart(dev, part);
 +      printf("switch to partitions #%d, %s\n",
 +             part, (!ret) ? "OK" : "ERROR");
 +      if (ret)
 +              return 1;
  
 -                              printf("switch to partions #%d, %s\n",
 -                                              part, (!ret) ? "OK" : "ERROR");
 -                      }
 -              }
 -              curr_device = dev;
 -              if (mmc->part_config == MMCPART_NOAVAILABLE)
 -                      printf("mmc%d is current device\n", curr_device);
 -              else
 -                      printf("mmc%d(part %d) is current device\n",
 -                              curr_device, mmc->part_num);
 +      curr_device = dev;
 +      if (mmc->part_config == MMCPART_NOAVAILABLE)
 +              printf("mmc%d is current device\n", curr_device);
 +      else
 +              printf("mmc%d(part %d) is current device\n",
 +                     curr_device, mmc->part_num);
  
 -              return CMD_RET_SUCCESS;
 +      return CMD_RET_SUCCESS;
 +}
 +static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
 +                     int argc, char * const argv[])
 +{
 +      print_mmc_devices('\n');
 +      return CMD_RET_SUCCESS;
 +}
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
 -      } else if ((strcmp(argv[1], "open") == 0) ||
 -                      (strcmp(argv[1], "close") == 0)) {
 -              int dev;
 -              struct mmc *mmc;
 -              u8 part_num, access = 0;
 -
 -              if (argc == 4) {
 -                      dev = simple_strtoul(argv[2], NULL, 10);
 -                      part_num = simple_strtoul(argv[3], NULL, 10);
 -              } else {
 -                      return CMD_RET_USAGE;
 -              }
 +static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
 +                        int argc, char * const argv[])
 +{
 +      int dev;
 +      struct mmc *mmc;
 +      u8 width, reset, mode;
  
 -              mmc = find_mmc_device(dev);
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", dev);
 -                      return CMD_RET_FAILURE;
 -              }
 +      if (argc != 5)
 +              return CMD_RET_USAGE;
 +      dev = simple_strtoul(argv[1], NULL, 10);
 +      width = simple_strtoul(argv[2], NULL, 10);
 +      reset = simple_strtoul(argv[3], NULL, 10);
 +      mode = simple_strtoul(argv[4], NULL, 10);
  
 -              if (IS_SD(mmc)) {
 -                      printf("SD device cannot be opened/closed\n");
 -                      return CMD_RET_FAILURE;
 -              }
 +      mmc = init_mmc_device(dev, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -              if ((part_num <= 0) || (part_num > MMC_NUM_BOOT_PARTITION)) {
 -                      printf("Invalid boot partition number:\n");
 -                      printf("Boot partition number cannot be <= 0\n");
 -                      printf("EMMC44 supports only 2 boot partitions\n");
 -                      return CMD_RET_FAILURE;
 -              }
 +      if (IS_SD(mmc)) {
 +              puts("BOOT_BUS_WIDTH only exists on eMMC\n");
 +              return CMD_RET_FAILURE;
 +      }
  
 -              if (strcmp(argv[1], "open") == 0)
 -                      access = part_num; /* enable R/W access to boot part*/
 -              else
 -                      access = 0; /* No access to boot partition */
 +      /* acknowledge to be sent during boot operation */
 +      return mmc_set_boot_bus_width(mmc, width, reset, mode);
 +}
 +static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag,
 +                            int argc, char * const argv[])
 +{
 +      int dev;
 +      struct mmc *mmc;
 +      u32 bootsize, rpmbsize;
  
 -              /* acknowledge to be sent during boot operation */
 -              return boot_part_access(mmc, 1, part_num, access);
 +      if (argc != 4)
 +              return CMD_RET_USAGE;
 +      dev = simple_strtoul(argv[1], NULL, 10);
 +      bootsize = simple_strtoul(argv[2], NULL, 10);
 +      rpmbsize = simple_strtoul(argv[3], NULL, 10);
  
 -      } else if (strcmp(argv[1], "bootpart") == 0) {
 -              int dev;
 +      mmc = init_mmc_device(dev, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -              if (argc != 5)
 -                      return CMD_RET_USAGE;
 +      if (IS_SD(mmc)) {
 +              printf("It is not a EMMC device\n");
 +              return CMD_RET_FAILURE;
 +      }
 +
 +      if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
 +              printf("EMMC boot partition Size change Failed.\n");
 +              return CMD_RET_FAILURE;
 +      }
  
 -              dev = simple_strtoul(argv[2], NULL, 10);
 +      printf("EMMC boot partition Size %d MB\n", bootsize);
 +      printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
 +      return CMD_RET_SUCCESS;
 +}
 +static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag,
 +                         int argc, char * const argv[])
 +{
 +      int dev;
 +      struct mmc *mmc;
 +      u8 ack, part_num, access;
  
 -              u32 bootsize = simple_strtoul(argv[3], NULL, 10);
 -              u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
 -              struct mmc *mmc = find_mmc_device(dev);
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", dev);
 -                      return CMD_RET_FAILURE;
 -              }
 +      if (argc != 5)
 +              return CMD_RET_USAGE;
  
 -              if (IS_SD(mmc)) {
 -                      printf("It is not a EMMC device\n");
 -                      return CMD_RET_FAILURE;
 -              }
 +      dev = simple_strtoul(argv[1], NULL, 10);
 +      ack = simple_strtoul(argv[2], NULL, 10);
 +      part_num = simple_strtoul(argv[3], NULL, 10);
 +      access = simple_strtoul(argv[4], NULL, 10);
  
 -              if (0 == mmc_boot_partition_size_change(mmc,
 -                                                      bootsize, rpmbsize)) {
 -                      printf("EMMC boot partition Size %d MB\n", bootsize);
 -                      printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
 -                      return CMD_RET_SUCCESS;
 -              } else {
 -                      printf("EMMC boot partition Size change Failed.\n");
 -                      return CMD_RET_FAILURE;
 -              }
 -#endif /* CONFIG_SUPPORT_EMMC_BOOT */
 +      mmc = init_mmc_device(dev, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
 +
 +      if (IS_SD(mmc)) {
 +              puts("PARTITION_CONFIG only exists on eMMC\n");
 +              return CMD_RET_FAILURE;
        }
 -      state = MMC_INVALID;
 -      if (argc == 5 && strcmp(argv[1], "read") == 0)
 -              state = MMC_READ;
 -      else if (argc == 5 && strcmp(argv[1], "write") == 0)
 -              state = MMC_WRITE;
 -      else if (argc == 4 && strcmp(argv[1], "erase") == 0)
 -              state = MMC_ERASE;
 -
 -      if (state != MMC_INVALID) {
 -              struct mmc *mmc = find_mmc_device(curr_device);
 -              int idx = 2;
 -              u32 blk, cnt, n;
 -              void *addr;
 -
 -              if (state != MMC_ERASE) {
 -                      addr = (void *)simple_strtoul(argv[idx], NULL, 16);
 -                      ++idx;
 -              } else
 -                      addr = NULL;
 -              blk = simple_strtoul(argv[idx], NULL, 16);
 -              cnt = simple_strtoul(argv[idx + 1], NULL, 16);
 -
 -              if (!mmc) {
 -                      printf("no mmc device at slot %x\n", curr_device);
 -                      return CMD_RET_FAILURE;
 -              }
  
 -              printf("\nMMC %s: dev # %d, block # %d, count %d ... ",
 -                              argv[1], curr_device, blk, cnt);
 +      /* acknowledge to be sent during boot operation */
 +      return mmc_set_part_conf(mmc, ack, part_num, access);
 +}
 +static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
 +                         int argc, char * const argv[])
 +{
 +      int dev;
 +      struct mmc *mmc;
 +      u8 enable;
 +
 +      /*
 +       * Set the RST_n_ENABLE bit of RST_n_FUNCTION
 +       * The only valid values are 0x0, 0x1 and 0x2 and writing
 +       * a value of 0x1 or 0x2 sets the value permanently.
 +       */
 +      if (argc != 3)
 +              return CMD_RET_USAGE;
  
 -              mmc_init(mmc);
 +      dev = simple_strtoul(argv[1], NULL, 10);
 +      enable = simple_strtoul(argv[2], NULL, 10);
  
 -              if ((state == MMC_WRITE || state == MMC_ERASE)) {
 -                      if (mmc_getwp(mmc) == 1) {
 -                              printf("Error: card is write protected!\n");
 -                              return CMD_RET_FAILURE;
 -                      }
 -              }
 +      if (enable > 2 || enable < 0) {
 +              puts("Invalid RST_n_ENABLE value\n");
 +              return CMD_RET_USAGE;
 +      }
  
 -              switch (state) {
 -              case MMC_READ:
 -                      n = mmc->block_dev.block_read(curr_device, blk,
 -                                                    cnt, addr);
 -                      /* flush cache after read */
 -                      flush_cache((ulong)addr, cnt * 512); /* FIXME */
 -                      break;
 -              case MMC_WRITE:
 -                      n = mmc->block_dev.block_write(curr_device, blk,
 -                                                    cnt, addr);
 -                      break;
 -              case MMC_ERASE:
 -                      n = mmc->block_dev.block_erase(curr_device, blk, cnt);
 -                      break;
 -              default:
 -                      BUG();
 -              }
 +      mmc = init_mmc_device(dev, false);
 +      if (!mmc)
 +              return CMD_RET_FAILURE;
  
 -              printf("%d blocks %s: %s\n",
 -                              n, argv[1], (n == cnt) ? "OK" : "ERROR");
 -              return (n == cnt) ? 0 : 1;
 +      if (IS_SD(mmc)) {
 +              puts("RST_n_FUNCTION only exists on eMMC\n");
 +              return CMD_RET_FAILURE;
 +      }
 +
 +      return mmc_set_rst_n_function(mmc, enable);
 +}
 +#endif
 +static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag,
 +                       int argc, char * const argv[])
 +{
 +      struct mmc *mmc;
 +      u32 val;
 +      int ret;
 +
 +      if (argc != 2)
 +              return CMD_RET_USAGE;
 +      val = simple_strtoul(argv[2], NULL, 16);
 +
 +      mmc = find_mmc_device(curr_device);
 +      if (!mmc) {
 +              printf("no mmc device at slot %x\n", curr_device);
 +              return CMD_RET_FAILURE;
 +      }
 +      ret = mmc_set_dsr(mmc, val);
 +      printf("set dsr %s\n", (!ret) ? "OK, force rescan" : "ERROR");
 +      if (!ret) {
 +              mmc->has_init = 0;
 +              if (mmc_init(mmc))
 +                      return CMD_RET_FAILURE;
 +              else
 +                      return CMD_RET_SUCCESS;
        }
 +      return ret;
 +}
 +
 +static cmd_tbl_t cmd_mmc[] = {
 +      U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
 +      U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
 +      U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
 +      U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
 +      U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
 +      U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
 +      U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
 +      U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
 +#ifdef CONFIG_SUPPORT_EMMC_BOOT
 +      U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
 +      U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
 +      U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
 +      U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
 +#endif
 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
 +      U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
 +#endif
 +      U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
 +};
 +
 +static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 +{
 +      cmd_tbl_t *cp;
 +
 +      cp = find_cmd_tbl(argv[1], cmd_mmc, ARRAY_SIZE(cmd_mmc));
 +
 +      /* Drop the mmc command */
 +      argc--;
 +      argv++;
 +
 +      if (cp == NULL || argc > cp->maxargs)
 +              return CMD_RET_USAGE;
 +      if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
 +              return CMD_RET_SUCCESS;
  
 -      return CMD_RET_USAGE;
 +      if (curr_device < 0) {
 +              if (get_mmc_num() > 0) {
 +                      curr_device = 0;
 +              } else {
 +                      puts("No MMC device available\n");
 +                      return CMD_RET_FAILURE;
 +              }
 +      }
 +      return cp->cmd(cmdtp, flag, argc, argv);
  }
  
  U_BOOT_CMD(
 -      mmc, 6, 1, do_mmcops,
 +      mmc, 7, 1, do_mmcops,
        "MMC sub system",
 -      "read addr blk# cnt\n"
 +      "info - display info of the current MMC device\n"
 +      "mmc read addr blk# cnt\n"
        "mmc write addr blk# cnt\n"
        "mmc erase blk# cnt\n"
        "mmc rescan\n"
        "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
        "mmc list - lists available devices\n"
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
 -      "mmc open <dev> <boot_partition>\n"
 -      " - Enable boot_part for booting and enable R/W access of boot_part\n"
 -      "mmc close <dev> <boot_partition>\n"
 -      " - Enable boot_part for booting and disable access to boot_part\n"
 -      "mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n"
 -      " - change sizes of boot and RPMB partions of specified device\n"
 +      "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
 +      " - Set the BOOT_BUS_WIDTH field of the specified device\n"
 +      "mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>\n"
 +      " - Change sizes of boot and RPMB partitions of specified device\n"
 +      "mmc partconf dev boot_ack boot_partition partition_access\n"
 +      " - Change the bits of the PARTITION_CONFIG field of the specified device\n"
 +      "mmc rst-function dev value\n"
 +      " - Change the RST_n_FUNCTION field of the specified device\n"
 +      "   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n"
  #endif
 +#ifdef CONFIG_SUPPORT_EMMC_RPMB
 +      "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
 +      "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
 +      "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"
 +      "mmc rpmb counter - read the value of the write counter\n"
 +#endif
 +      "mmc setdsr <value> - set DSR register value\n"
        );
 +
 +/* Old command kept for compatibility. Same as 'mmc info' */
 +U_BOOT_CMD(
 +      mmcinfo, 1, 0, do_mmcinfo,
 +      "display MMC info",
 +      "- display info of the current MMC device"
 +);
 +
  #endif /* !CONFIG_GENERIC_MMC */
diff --combined common/cmd_mtdparts.c
index 422c069513843f930ce1eeccf2a9aa2e89b7fcf1,8cc5c383b6d97e165cbe68f95ed31d89dc006468..3e34558acfd1a38ec4527e2618cf9db9ea7271fd
  DECLARE_GLOBAL_DATA_PTR;
  
  /* special size referring to all the remaining space in a partition */
 -#define SIZE_REMAINING                0xFFFFFFFF
 +#define SIZE_REMAINING                (~0llu)
  
  /* special offset value, it is used when not provided by user
   *
   * this value is used temporarily during parsing, later such offests
   * are recalculated */
 -#define OFFSET_NOT_SPECIFIED  0xFFFFFFFF
 +#define OFFSET_NOT_SPECIFIED  (~0llu)
  
  /* minimum partition size */
  #define MIN_PART_SIZE         4096
@@@ -160,9 -160,9 +160,9 @@@ static int device_del(struct mtd_devic
   * @param retptr output pointer to next char after parse completes (output)
   * @return resulting unsigned int
   */
 -static unsigned long memsize_parse (const char *const ptr, const char **retptr)
 +static u64 memsize_parse (const char *const ptr, const char **retptr)
  {
 -      unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
 +      u64 ret = simple_strtoull(ptr, (char **)retptr, 0);
  
        switch (**retptr) {
                case 'G':
   * @param buf output buffer
   * @param size size to be converted to string
   */
 -static void memsize_format(char *buf, u32 size)
 +static void memsize_format(char *buf, u64 size)
  {
  #define SIZE_GB ((u32)1024*1024*1024)
  #define SIZE_MB ((u32)1024*1024)
  #define SIZE_KB ((u32)1024)
  
        if ((size % SIZE_GB) == 0)
 -              sprintf(buf, "%ug", size/SIZE_GB);
 +              sprintf(buf, "%llug", size/SIZE_GB);
        else if ((size % SIZE_MB) == 0)
 -              sprintf(buf, "%um", size/SIZE_MB);
 +              sprintf(buf, "%llum", size/SIZE_MB);
        else if (size % SIZE_KB == 0)
 -              sprintf(buf, "%uk", size/SIZE_KB);
 +              sprintf(buf, "%lluk", size/SIZE_KB);
        else
 -              sprintf(buf, "%u", size);
 +              sprintf(buf, "%llu", size);
  }
  
  /**
@@@ -292,7 -292,6 +292,7 @@@ static int get_mtd_info(u8 type, u8 num
                printf("Device %s not found!\n", mtd_dev);
                return 1;
        }
 +      put_mtd_device(*mtd);
  
        return 0;
  }
@@@ -311,7 -310,6 +311,7 @@@ static int part_validate_eraseblock(str
        struct mtd_info *mtd = NULL;
        int i, j;
        ulong start;
 +      u64 offset, size;
  
        if (get_mtd_info(id->type, id->num, &mtd))
                return 1;
                 * Only one eraseregion (NAND, OneNAND or uniform NOR),
                 * checking for alignment is easy here
                 */
 -              if ((unsigned long)part->offset % mtd->erasesize) {
 +              offset = part->offset;
 +              if (do_div(offset, mtd->erasesize)) {
-                       printf("%s%d: partition (%s) start offset"
-                              "alignment incorrect\n",
+                       printf("%s%d: partition (%s) start offset alignment incorrect\n",
                               MTD_DEV_TYPE(id->type), id->num, part->name);
                        return 1;
                }
  
 -              if (part->size % mtd->erasesize) {
 +              size = part->size;
 +              if (do_div(size, mtd->erasesize)) {
                        printf("%s%d: partition (%s) size alignment incorrect\n",
                               MTD_DEV_TYPE(id->type), id->num, part->name);
                        return 1;
  
  
  /**
 - * Performs sanity check for supplied partition. Offset and size are verified
 - * to be within valid range. Partition type is checked and either
 - * parts_validate_nor() or parts_validate_nand() is called with the argument
 - * of part.
 + * Performs sanity check for supplied partition. Offset and size are
 + * verified to be within valid range. Partition type is checked and
 + * part_validate_eraseblock() is called with the argument of part.
   *
   * @param id of the parent device
   * @param part partition to validate
@@@ -399,7 -395,7 +398,7 @@@ static int part_validate(struct mtdids 
                part->size = id->size - part->offset;
  
        if (part->offset > id->size) {
 -              printf("%s: offset %08x beyond flash size %08x\n",
 +              printf("%s: offset %08llx beyond flash size %08llx\n",
                                id->mtd_id, part->offset, id->size);
                return 1;
        }
  }
  
  /**
 - * Delete selected partition from the partion list of the specified device.
 + * Delete selected partition from the partition list of the specified device.
   *
   * @param dev device to delete partition from
   * @param part partition to delete
@@@ -582,8 -578,8 +581,8 @@@ static int part_add(struct mtd_device *
  static int part_parse(const char *const partdef, const char **ret, struct part_info **retpart)
  {
        struct part_info *part;
 -      unsigned long size;
 -      unsigned long offset;
 +      u64 size;
 +      u64 offset;
        const char *name;
        int name_len;
        unsigned int mask_flags;
        } else {
                size = memsize_parse(p, &p);
                if (size < MIN_PART_SIZE) {
 -                      printf("partition size too small (%lx)\n", size);
 +                      printf("partition size too small (%llx)\n", size);
                        return 1;
                }
        }
                part->auto_name = 0;
        } else {
                /* auto generated name in form of size@offset */
 -              sprintf(part->name, "0x%08lx@0x%08lx", size, offset);
 +              sprintf(part->name, "0x%08llx@0x%08llx", size, offset);
                part->auto_name = 1;
        }
  
        part->name[name_len - 1] = '\0';
        INIT_LIST_HEAD(&part->link);
  
 -      debug("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n",
 +      debug("+ partition: name %-22s size 0x%08llx offset 0x%08llx mask flags %d\n",
                        part->name, part->size,
                        part->offset, part->mask_flags);
  
   * @param size a pointer to the size of the mtd device (output)
   * @return 0 if device is valid, 1 otherwise
   */
 -static int mtd_device_validate(u8 type, u8 num, u32 *size)
 +static int mtd_device_validate(u8 type, u8 num, u64 *size)
  {
        struct mtd_info *mtd = NULL;
  
@@@ -830,7 -826,7 +829,7 @@@ static int device_parse(const char *con
        LIST_HEAD(tmp_list);
        struct list_head *entry, *n;
        u16 num_parts;
 -      u32 offset;
 +      u64 offset;
        int err = 1;
  
        debug("===device_parse===\n");
        debug("dev type = %d (%s), dev num = %d, mtd-id = %s\n",
                        id->type, MTD_DEV_TYPE(id->type),
                        id->num, id->mtd_id);
 -      debug("parsing partitions %.*s\n", (pend ? pend - p : strlen(p)), p);
 +      debug("parsing partitions %.*s\n", (int)(pend ? pend - p : strlen(p)), p);
  
  
        /* parse partitions */
@@@ -1007,7 -1003,7 +1006,7 @@@ static struct mtdids* id_find_by_mtd_id
        list_for_each(entry, &mtdids) {
                id = list_entry(entry, struct mtdids, link);
  
 -              debug("entry: '%s' (len = %d)\n",
 +              debug("entry: '%s' (len = %zu)\n",
                                id->mtd_id, strlen(id->mtd_id));
  
                if (mtd_id_len != strlen(id->mtd_id))
@@@ -1075,8 -1071,7 +1074,8 @@@ static int generate_mtdparts(char *buf
        struct part_info *part, *prev_part;
        char *p = buf;
        char tmpbuf[32];
 -      u32 size, offset, len, part_cnt;
 +      u64 size, offset;
 +      u32 len, part_cnt;
        u32 maxlen = buflen - 1;
  
        debug("--- generate_mtdparts ---\n");
@@@ -1275,7 -1270,7 +1274,7 @@@ static void print_partition_table(void
  
                list_for_each(pentry, &dev->parts) {
                        part = list_entry(pentry, struct part_info, link);
 -                      printf("%2d: %-20s0x%08x\t0x%08x\t%d\n",
 +                      printf("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
                                        part_num, part->name, part->size,
                                        part->offset, part->mask_flags);
  #endif /* defined(CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES) */
@@@ -1302,7 -1297,7 +1301,7 @@@ static void list_partitions(void
        if (current_mtd_dev) {
                part = mtd_part_info(current_mtd_dev, current_mtd_partnum);
                if (part) {
 -                      printf("\nactive partition: %s%d,%d - (%s) 0x%08x @ 0x%08x\n",
 +                      printf("\nactive partition: %s%d,%d - (%s) 0x%08llx @ 0x%08llx\n",
                                        MTD_DEV_TYPE(current_mtd_dev->id->type),
                                        current_mtd_dev->id->num, current_mtd_partnum,
                                        part->name, part->size, part->offset);
@@@ -1402,7 -1397,7 +1401,7 @@@ static int delete_partition(const char 
  
        if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {
  
 -              debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08x@0x%08x\n",
 +              debug("delete_partition: device = %s%d, partition %d = (%s) 0x%08llx@0x%08llx\n",
                                MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum,
                                part->name, part->size, part->offset);
  
@@@ -1594,7 -1589,7 +1593,7 @@@ static int parse_mtdids(const char *con
        struct list_head *entry, *n;
        struct mtdids *id_tmp;
        u8 type, num;
 -      u32 size;
 +      u64 size;
        int ret = 1;
  
        debug("\n---parse_mtdids---\nmtdids = %s\n\n", ids);
                id->mtd_id[mtd_id_len - 1] = '\0';
                INIT_LIST_HEAD(&id->link);
  
 -              debug("+ id %s%d\t%16d bytes\t%s\n",
 +              debug("+ id %s%d\t%16lld bytes\t%s\n",
                                MTD_DEV_TYPE(id->type), id->num,
                                id->size, id->mtd_id);
  
diff --combined common/cmd_nand.c
index 7f962dcb25a080f892fde9d6b79934d9f428f6fd,be14b5f6caeb2192f6309a0f43949a5b39f70016..7d477aac56f93c62119bf95d7f5789de85f0930c
@@@ -42,7 -42,6 +42,7 @@@ static int nand_dump(nand_info_t *nand
        int i;
        u_char *datbuf, *oobbuf, *p;
        static loff_t last;
 +      int ret = 0;
  
        if (repeat)
                off = last + nand->writesize;
        last = off;
  
        datbuf = memalign(ARCH_DMA_MINALIGN, nand->writesize);
 -      oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize);
 -      if (!datbuf || !oobbuf) {
 +      if (!datbuf) {
                puts("No memory for page buffer\n");
                return 1;
        }
 +
 +      oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize);
 +      if (!oobbuf) {
 +              puts("No memory for page buffer\n");
 +              ret = 1;
 +              goto free_dat;
 +      }
        off &= ~(nand->writesize - 1);
        loff_t addr = (loff_t) off;
        struct mtd_oob_ops ops;
        i = mtd_read_oob(nand, addr, &ops);
        if (i < 0) {
                printf("Error (%d) reading page %08lx\n", i, off);
 -              free(datbuf);
 -              free(oobbuf);
 -              return 1;
 +              ret = 1;
 +              goto free_all;
        }
        printf("Page %08lx dump:\n", off);
 -      i = nand->writesize >> 4;
 -      p = datbuf;
  
 -      while (i--) {
 -              if (!only_oob)
 +      if (!only_oob) {
 +              i = nand->writesize >> 4;
 +              p = datbuf;
 +
 +              while (i--) {
                        printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
                               "  %02x %02x %02x %02x %02x %02x %02x %02x\n",
                               p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
                               p[8], p[9], p[10], p[11], p[12], p[13], p[14],
                               p[15]);
 -              p += 16;
 +                      p += 16;
 +              }
        }
 +
        puts("OOB:\n");
        i = nand->oobsize >> 3;
        p = oobbuf;
                       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
                p += 8;
        }
 -      free(datbuf);
 +
 +free_all:
        free(oobbuf);
 +free_dat:
 +      free(datbuf);
  
 -      return 0;
 +      return ret;
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -489,7 -477,7 +489,7 @@@ static int do_nand(cmd_tbl_t *cmdtp, in
  
        /* Only "dump" is repeatable. */
        if (repeat && strcmp(cmd, "dump"))
-               return 0;
+               return CMD_RET_FAILURE;
  
        if (strcmp(cmd, "info") == 0) {
  
                        if (nand_info[i].name)
                                nand_print_and_set_info(i);
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
  
        if (strcmp(cmd, "device") == 0) {
                                puts("no devices available\n");
                        else
                                nand_print_and_set_info(dev);
-                       return 0;
+                       return CMD_RET_SUCCESS;
                }
  
                dev = (int)simple_strtoul(argv[2], NULL, 10);
                set_dev(dev);
  
-               return 0;
+               return CMD_RET_SUCCESS;
        }
  
  #ifdef CONFIG_ENV_OFFSET_OOB
        /* this command operates only on the first nand device */
        if (strcmp(cmd, "env.oob") == 0)
-               return do_nand_env_oob(cmdtp, argc - 1, argv + 1);
+               return do_nand_env_oob(cmdtp, argc - 1, argv + 1) ?
+                       CMD_RET_FAILURE : CMD_RET_SUCCESS;;
  #endif
  
        /* The following commands operate on the current device, unless
        if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
            !nand_info[dev].name) {
                puts("\nno devices available\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
        nand = &nand_info[dev];
  
                for (off = 0; off < nand->size; off += nand->erasesize)
                        if (nand_block_isbad(nand, off))
                                printf("  %08llx\n", (unsigned long long)off);
-               return 0;
+               return CMD_RET_SUCCESS;
        }
  
        /*
                /* skip first two or three arguments, look for offset and size */
                if (arg_off_size(argc - o, argv + o, &dev, &off, &size,
                                 &maxsize) != 0)
-                       return 1;
+                       return CMD_RET_FAILURE;
  
                nand = &nand_info[dev];
  
                opts.spread = spread;
  
                if (scrub) {
 -                      if (!scrub_yes)
 -                              puts(scrub_warn);
 -
 -                      if (scrub_yes)
 +                      if (scrub_yes) {
                                opts.scrub = 1;
 -                      else if (getc() == 'y') {
 -                              puts("y");
 -                              if (getc() == '\r')
 +                      } else {
 +                              puts(scrub_warn);
 +                              if (confirm_yesno()) {
                                        opts.scrub = 1;
 -                              else {
 +                              else {
                                        puts("scrub aborted\n");
-                                       return 1;
+                                       return CMD_RET_FAILURE;
                                }
 -                      } else {
 -                              puts("scrub aborted\n");
 -                              return CMD_RET_FAILURE;
                        }
                }
                ret = nand_erase_opts(nand, &opts);
                printf("%s\n", ret ? "ERROR" : "OK");
  
-               return ret == 0 ? 0 : 1;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
  
        if (strncmp(cmd, "dump", 4) == 0) {
                off = (int)simple_strtoul(argv[2], NULL, 16);
                ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
  
-               return ret == 0 ? 1 : 0;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
  
        if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
                read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
                printf("\nNAND %s: ", read ? "read" : "write");
  
 -              nand = &nand_info[dev];
 -
                s = strchr(cmd, '.');
  
                if (s && !strcmp(s, ".raw")) {
                        if (arg_off(argv[3], &dev, &off, &size, &maxsize))
                                return 1;
  
 +                      nand = &nand_info[dev];
 +
                        if (argc > 4 && !str2long(argv[4], &pagecount)) {
                                printf("'%s' is not a number\n", argv[4]);
                                return 1;
                        rwsize = size;
                }
  
 +              nand = &nand_info[dev];
 +
                if (!s || !strcmp(s, ".jffs2") ||
                    !strcmp(s, ".e") || !strcmp(s, ".i")) {
                        if (read)
                } else if (!strcmp(s, ".trimffs")) {
                        if (read) {
                                printf("Unknown nand command suffix '%s'\n", s);
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                        ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
                                                maxsize, (u_char *)addr,
                } else if (!strcmp(s, ".yaffs")) {
                        if (read) {
                                printf("Unknown nand command suffix '%s'.\n", s);
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                        ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
                                                maxsize, (u_char *)addr,
                        ret = raw_access(nand, addr, off, pagecount, read);
                } else {
                        printf("Unknown nand command suffix '%s'.\n", s);
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
  
                printf(" %zu bytes %s: %s\n", rwsize,
                       read ? "read" : "written", ret ? "ERROR" : "OK");
  
-               return ret == 0 ? 0 : 1;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
  
  #ifdef CONFIG_CMD_NAND_TORTURE
                        --argc;
                        ++argv;
                }
-               return ret;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
  
        if (strcmp(cmd, "biterr") == 0) {
                /* todo */
-               return 1;
+               return CMD_RET_FAILURE;
        }
  
  #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
                                puts("NAND flash successfully locked\n");
                        } else {
                                puts("Error locking NAND flash\n");
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
  
        if (strncmp(cmd, "unlock", 5) == 0) {
  
                if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
                                 &maxsize) < 0)
-                       return 1;
+                       return CMD_RET_FAILURE;
  
                if (!nand_unlock(&nand_info[dev], off, size, allexcept)) {
                        puts("NAND flash successfully unlocked\n");
                } else {
                        puts("Error unlocking NAND flash, "
                             "write and erase will probably fail\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
  #endif
  
@@@ -900,9 -893,7 +901,9 @@@ static int nand_load_image(cmd_tbl_t *c
        int r;
        char *s;
        size_t cnt;
 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
        image_header_t *hdr;
 +#endif
  #if defined(CONFIG_FIT)
        const void *fit_hdr = NULL;
  #endif
        bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ);
  
        switch (genimg_get_format ((void *)addr)) {
 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
        case IMAGE_FORMAT_LEGACY:
                hdr = (image_header_t *)addr;
  
  
                cnt = image_get_image_size (hdr);
                break;
 +#endif
  #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
                fit_hdr = (const void *)addr;
diff --combined common/env_nand.c
index 9c9bb82c0faf81f3d6d6295f99ecfcfd3a1cea2b,9ae28ecbe7aa3dbc80bffc21cf1e553894a6b0ec..dc457f959d708e98cba41b8714d340748f687c4d
@@@ -11,7 -11,7 +11,7 @@@
   * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   * Andreas Heppel <aheppel@sysgo.de>
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #include <common.h>
@@@ -44,8 -44,6 +44,6 @@@ char *env_name_spec = "NAND"
  env_t *env_ptr = &environment;
  #elif defined(CONFIG_NAND_ENV_DST)
  env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
- #else /* ! ENV_IS_EMBEDDED */
- env_t *env_ptr;
  #endif /* ENV_IS_EMBEDDED */
  
  DECLARE_GLOBAL_DATA_PTR;
@@@ -124,7 -122,7 +122,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;
        u_char *char_ptr;
  
        blocksize = nand_info[0].erasesize;
 -      len = min(blocksize, CONFIG_ENV_SIZE);
 +      len = min(blocksize, (size_t)CONFIG_ENV_SIZE);
  
        while (amount_saved < CONFIG_ENV_SIZE && offset < end) {
                if (nand_block_isbad(&nand_info[0], offset)) {
        return 0;
  }
  
 -#ifdef CONFIG_ENV_OFFSET_REDUND
 -static unsigned char env_flags;
 +struct env_location {
 +      const char *name;
 +      const nand_erase_options_t erase_opts;
 +};
  
 -int saveenv(void)
 +static int erase_and_write_env(const struct env_location *location,
 +              u_char *env_new)
  {
 -      env_t   env_new;
 -      ssize_t len;
 -      char    *res;
 -      int     ret = 0;
 -      nand_erase_options_t nand_erase_options;
 -
 -      memset(&nand_erase_options, 0, sizeof(nand_erase_options));
 -      nand_erase_options.length = CONFIG_ENV_RANGE;
 +      int ret = 0;
  
 -      if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
 -              return 1;
 -
 -      res = (char *)&env_new.data;
 -      len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 -      if (len < 0) {
 -              error("Cannot export environment: errno = %d\n", errno);
 +      printf("Erasing %s...\n", location->name);
 +      if (nand_erase_opts(&nand_info[0], &location->erase_opts))
                return 1;
 -      }
 -      env_new.crc     = crc32(0, env_new.data, ENV_SIZE);
 -      env_new.flags   = ++env_flags; /* increase the serial */
 -
 -      if (gd->env_valid == 1) {
 -              puts("Erasing redundant NAND...\n");
 -              nand_erase_options.offset = CONFIG_ENV_OFFSET_REDUND;
 -              if (nand_erase_opts(&nand_info[0], &nand_erase_options))
 -                      return 1;
 -
 -              puts("Writing to redundant NAND... ");
 -              ret = writeenv(CONFIG_ENV_OFFSET_REDUND, (u_char *)&env_new);
 -      } else {
 -              puts("Erasing NAND...\n");
 -              nand_erase_options.offset = CONFIG_ENV_OFFSET;
 -              if (nand_erase_opts(&nand_info[0], &nand_erase_options))
 -                      return 1;
 -
 -              puts("Writing to NAND... ");
 -              ret = writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new);
 -      }
 -      if (ret) {
 -              puts("FAILED!\n");
 -              return 1;
 -      }
 -
 -      puts("done\n");
  
 -      gd->env_valid = gd->env_valid == 2 ? 1 : 2;
 +      printf("Writing to %s... ", location->name);
 +      ret = writeenv(location->erase_opts.offset, env_new);
 +      puts(ret ? "FAILED!\n" : "OK\n");
  
        return ret;
  }
 -#else /* ! CONFIG_ENV_OFFSET_REDUND */
 +
 +#ifdef CONFIG_ENV_OFFSET_REDUND
 +static unsigned char env_flags;
 +#endif
 +
  int saveenv(void)
  {
        int     ret = 0;
        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
 -      ssize_t len;
 -      char    *res;
 -      nand_erase_options_t nand_erase_options;
 +      int     env_idx = 0;
 +      static const struct env_location location[] = {
 +              {
 +                      .name = "NAND",
 +                      .erase_opts = {
 +                              .length = CONFIG_ENV_RANGE,
 +                              .offset = CONFIG_ENV_OFFSET,
 +                      },
 +              },
 +#ifdef CONFIG_ENV_OFFSET_REDUND
 +              {
 +                      .name = "redundant NAND",
 +                      .erase_opts = {
 +                              .length = CONFIG_ENV_RANGE,
 +                              .offset = CONFIG_ENV_OFFSET_REDUND,
 +                      },
 +              },
 +#endif
 +      };
  
 -      memset(&nand_erase_options, 0, sizeof(nand_erase_options));
 -      nand_erase_options.length = CONFIG_ENV_RANGE;
 -      nand_erase_options.offset = CONFIG_ENV_OFFSET;
  
        if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
                return 1;
  
 -      res = (char *)&env_new->data;
 -      len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 -      if (len < 0) {
 -              error("Cannot export environment: errno = %d\n", errno);
 -              return 1;
 -      }
 -      env_new->crc = crc32(0, env_new->data, ENV_SIZE);
 +      ret = env_export(env_new);
 +      if (ret)
 +              return ret;
  
 -      puts("Erasing Nand...\n");
 -      if (nand_erase_opts(&nand_info[0], &nand_erase_options))
 -              return 1;
 +#ifdef CONFIG_ENV_OFFSET_REDUND
 +      env_new->flags = ++env_flags; /* increase the serial */
 +      env_idx = (gd->env_valid == 1);
 +#endif
  
 -      puts("Writing to Nand... ");
 -      if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) {
 -              puts("FAILED!\n");
 -              return 1;
 +      ret = erase_and_write_env(&location[env_idx], (u_char *)env_new);
 +#ifdef CONFIG_ENV_OFFSET_REDUND
 +      if (!ret) {
 +              /* preset other copy for next write */
 +              gd->env_valid = gd->env_valid == 2 ? 1 : 2;
 +              return ret;
        }
  
 -      puts("done\n");
 +      env_idx = (env_idx + 1) & 1;
 +      ret = erase_and_write_env(&location[env_idx], (u_char *)env_new);
 +      if (!ret)
 +              printf("Warning: primary env write failed,"
 +                              " redundancy is lost!\n");
 +#endif
 +
        return ret;
  }
 -#endif /* CONFIG_ENV_OFFSET_REDUND */
  #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;
        if (!blocksize)
                return 1;
  
 -      len = min(blocksize, CONFIG_ENV_SIZE);
 +      len = min(blocksize, (size_t)CONFIG_ENV_SIZE);
  
        while (amount_loaded < CONFIG_ENV_SIZE && offset < end) {
                if (nand_block_isbad(&nand_info[0], offset)) {
@@@ -350,7 -361,9 +348,9 @@@ void env_relocate_spec(void
                        gd->env_valid = 1;
        }
  
+ #ifdef CONFIG_NAND_ENV_DST
        free(env_ptr);
+ #endif
  
        if (gd->env_valid == 1)
                ep = tmp_env1;
diff --combined common/fdt_support.c
index 8266bca7d6489a2ca8fb6f1015064184b137d2dd,ce7527a931563f49fa585964451b60c1415a2816..897ace6295bf831e10bbe7c52820c43f105d6e15
@@@ -8,7 -8,6 +8,7 @@@
   */
  
  #include <common.h>
 +#include <inttypes.h>
  #include <stdio_dev.h>
  #include <linux/ctype.h>
  #include <linux/types.h>
  #include <fdt_support.h>
  #include <exports.h>
  
 -/*
 - * Global data (for the gd->bd)
 +/**
 + * fdt_getprop_u32_default_node - Return a node's property or a default
 + *
 + * @fdt: ptr to device tree
 + * @off: offset of node
 + * @cell: cell offset in property
 + * @prop: property name
 + * @dflt: default value if the property isn't found
 + *
 + * Convenience function to return a node's property or a default value if
 + * the property doesn't exist.
   */
 -DECLARE_GLOBAL_DATA_PTR;
 +u32 fdt_getprop_u32_default_node(const void *fdt, int off, int cell,
 +                              const char *prop, const u32 dflt)
 +{
 +      const fdt32_t *val;
 +      int len;
 +
 +      val = fdt_getprop(fdt, off, prop, &len);
 +
 +      /* Check if property exists */
 +      if (!val)
 +              return dflt;
 +
 +      /* Check if property is long enough */
 +      if (len < ((cell + 1) * sizeof(uint32_t)))
 +              return dflt;
 +
 +      return fdt32_to_cpu(*val);
 +}
  
  /**
   * fdt_getprop_u32_default - Find a node and return it's property or a default
  u32 fdt_getprop_u32_default(const void *fdt, const char *path,
                                const char *prop, const u32 dflt)
  {
 -      const fdt32_t *val;
        int off;
  
        off = fdt_path_offset(fdt, path);
        if (off < 0)
                return dflt;
  
 -      val = fdt_getprop(fdt, off, prop, NULL);
 -      if (val)
 -              return fdt32_to_cpu(*val);
 -      else
 -              return dflt;
 +      return fdt_getprop_u32_default_node(fdt, off, 0, prop, dflt);
  }
  
  /**
@@@ -97,39 -75,9 +97,39 @@@ int fdt_find_and_setprop(void *fdt, con
        return fdt_setprop(fdt, nodeoff, prop, val, len);
  }
  
 -#ifdef CONFIG_OF_STDOUT_VIA_ALIAS
 +/**
 + * fdt_find_or_add_subnode() - find or possibly add a subnode of a given node
 + *
 + * @fdt: pointer to the device tree blob
 + * @parentoffset: structure block offset of a node
 + * @name: name of the subnode to locate
 + *
 + * fdt_subnode_offset() finds a subnode of the node with a given name.
 + * If the subnode does not exist, it will be created.
 + */
 +int fdt_find_or_add_subnode(void *fdt, int parentoffset, const char *name)
 +{
 +      int offset;
 +
 +      offset = fdt_subnode_offset(fdt, parentoffset, name);
 +
 +      if (offset == -FDT_ERR_NOTFOUND)
 +              offset = fdt_add_subnode(fdt, parentoffset, name);
 +
 +      if (offset < 0)
 +              printf("%s: %s: %s\n", __func__, name, fdt_strerror(offset));
 +
 +      return offset;
 +}
  
 -#ifdef CONFIG_CONS_INDEX
 +/* rename to CONFIG_OF_STDOUT_PATH ? */
 +#if defined(OF_STDOUT_PATH)
 +static int fdt_fixup_stdout(void *fdt, int chosenoff)
 +{
 +      return fdt_setprop(fdt, chosenoff, "linux,stdout-path",
 +                            OF_STDOUT_PATH, strlen(OF_STDOUT_PATH) + 1);
 +}
 +#elif defined(CONFIG_OF_STDOUT_VIA_ALIAS) && defined(CONFIG_CONS_INDEX)
  static void fdt_fill_multisername(char *sername, size_t maxlen)
  {
        const char *outname = stdio_devices[stdout]->name;
        if (strcmp(outname + 1, "serial") > 0)
                strncpy(sername, outname + 1, maxlen);
  }
 -#endif
  
  static int fdt_fixup_stdout(void *fdt, int chosenoff)
  {
 -      int err = 0;
 -#ifdef CONFIG_CONS_INDEX
 -      int node;
 +      int err;
 +      int aliasoff;
        char sername[9] = { 0 };
 -      const char *path;
 +      const void *path;
 +      int len;
 +      char tmp[256]; /* long enough */
  
        fdt_fill_multisername(sername, sizeof(sername) - 1);
        if (!sername[0])
                sprintf(sername, "serial%d", CONFIG_CONS_INDEX - 1);
  
 -      err = node = fdt_path_offset(fdt, "/aliases");
 -      if (node >= 0) {
 -              int len;
 -              path = fdt_getprop(fdt, node, sername, &len);
 -              if (path) {
 -                      char *p = malloc(len);
 -                      err = -FDT_ERR_NOSPACE;
 -                      if (p) {
 -                              memcpy(p, path, len);
 -                              err = fdt_setprop(fdt, chosenoff,
 -                                      "linux,stdout-path", p, len);
 -                              free(p);
 -                      }
 -              } else {
 -                      err = len;
 -              }
 +      aliasoff = fdt_path_offset(fdt, "/aliases");
 +      if (aliasoff < 0) {
 +              err = aliasoff;
 +              goto error;
        }
 -#endif
 +
 +      path = fdt_getprop(fdt, aliasoff, sername, &len);
 +      if (!path) {
 +              err = len;
 +              goto error;
 +      }
 +
 +      /* fdt_setprop may break "path" so we copy it to tmp buffer */
 +      memcpy(tmp, path, len);
 +
 +      err = fdt_setprop(fdt, chosenoff, "linux,stdout-path", tmp, len);
 +error:
        if (err < 0)
                printf("WARNING: could not set linux,stdout-path %s.\n",
 -                              fdt_strerror(err));
 +                     fdt_strerror(err));
  
        return err;
  }
 +#else
 +static int fdt_fixup_stdout(void *fdt, int chosenoff)
 +{
 +      return 0;
 +}
  #endif
  
 -int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 +static inline int fdt_setprop_uxx(void *fdt, int nodeoffset, const char *name,
 +                                uint64_t val, int is_u64)
 +{
 +      if (is_u64)
 +              return fdt_setprop_u64(fdt, nodeoffset, name, val);
 +      else
 +              return fdt_setprop_u32(fdt, nodeoffset, name, (uint32_t)val);
 +}
 +
 +
 +int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
  {
        int   nodeoffset;
        int   err, j, total;
 -      fdt32_t  tmp;
 -      const char *path;
 +      int is_u64;
        uint64_t addr, size;
  
 -      /* Find the "chosen" node.  */
 -      nodeoffset = fdt_path_offset (fdt, "/chosen");
 +      /* just return if the size of initrd is zero */
 +      if (initrd_start == initrd_end)
 +              return 0;
  
 -      /* If there is no "chosen" node in the blob return */
 -      if (nodeoffset < 0) {
 -              printf("fdt_initrd: %s\n", fdt_strerror(nodeoffset));
 +      /* find or create "/chosen" node. */
 +      nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
 +      if (nodeoffset < 0)
                return nodeoffset;
 -      }
 -
 -      /* just return if initrd_start/end aren't valid */
 -      if ((initrd_start == 0) || (initrd_end == 0))
 -              return 0;
  
        total = fdt_num_mem_rsv(fdt);
  
                return err;
        }
  
 -      path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
 -      if ((path == NULL) || force) {
 -              tmp = cpu_to_fdt32(initrd_start);
 -              err = fdt_setprop(fdt, nodeoffset,
 -                      "linux,initrd-start", &tmp, sizeof(tmp));
 -              if (err < 0) {
 -                      printf("WARNING: "
 -                              "could not set linux,initrd-start %s.\n",
 -                              fdt_strerror(err));
 -                      return err;
 -              }
 -              tmp = cpu_to_fdt32(initrd_end);
 -              err = fdt_setprop(fdt, nodeoffset,
 -                      "linux,initrd-end", &tmp, sizeof(tmp));
 -              if (err < 0) {
 -                      printf("WARNING: could not set linux,initrd-end %s.\n",
 -                              fdt_strerror(err));
 +      is_u64 = (fdt_address_cells(fdt, 0) == 2);
  
 -                      return err;
 -              }
 +      err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-start",
 +                            (uint64_t)initrd_start, is_u64);
 +
 +      if (err < 0) {
 +              printf("WARNING: could not set linux,initrd-start %s.\n",
 +                     fdt_strerror(err));
 +              return err;
 +      }
 +
 +      err = fdt_setprop_uxx(fdt, nodeoffset, "linux,initrd-end",
 +                            (uint64_t)initrd_end, is_u64);
 +
 +      if (err < 0) {
 +              printf("WARNING: could not set linux,initrd-end %s.\n",
 +                     fdt_strerror(err));
 +
 +              return err;
        }
  
        return 0;
  }
  
 -int fdt_chosen(void *fdt, int force)
 +int fdt_chosen(void *fdt)
  {
        int   nodeoffset;
        int   err;
        char  *str;             /* used to set string properties */
 -      const char *path;
  
        err = fdt_check_header(fdt);
        if (err < 0) {
                return err;
        }
  
 -      /*
 -       * Find the "chosen" node.
 -       */
 -      nodeoffset = fdt_path_offset (fdt, "/chosen");
 -
 -      /*
 -       * If there is no "chosen" node in the blob, create it.
 -       */
 -      if (nodeoffset < 0) {
 -              /*
 -               * Create a new node "/chosen" (offset 0 is root level)
 -               */
 -              nodeoffset = fdt_add_subnode(fdt, 0, "chosen");
 -              if (nodeoffset < 0) {
 -                      printf("WARNING: could not create /chosen %s.\n",
 -                              fdt_strerror(nodeoffset));
 -                      return nodeoffset;
 -              }
 -      }
 +      /* find or create "/chosen" node. */
 +      nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
 +      if (nodeoffset < 0)
 +              return nodeoffset;
  
 -      /*
 -       * Create /chosen properites that don't exist in the fdt.
 -       * If the property exists, update it only if the "force" parameter
 -       * is true.
 -       */
        str = getenv("bootargs");
 -      if (str != NULL) {
 -              path = fdt_getprop(fdt, nodeoffset, "bootargs", NULL);
 -              if ((path == NULL) || force) {
 -                      err = fdt_setprop(fdt, nodeoffset,
 -                              "bootargs", str, strlen(str)+1);
 -                      if (err < 0)
 -                              printf("WARNING: could not set bootargs %s.\n",
 -                                      fdt_strerror(err));
 +      if (str) {
 +              err = fdt_setprop(fdt, nodeoffset, "bootargs", str,
 +                                strlen(str) + 1);
 +              if (err < 0) {
 +                      printf("WARNING: could not set bootargs %s.\n",
 +                             fdt_strerror(err));
 +                      return err;
                }
        }
  
 -#ifdef CONFIG_OF_STDOUT_VIA_ALIAS
 -      path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
 -      if ((path == NULL) || force)
 -              err = fdt_fixup_stdout(fdt, nodeoffset);
 -#endif
 -
 -#ifdef OF_STDOUT_PATH
 -      path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
 -      if ((path == NULL) || force) {
 -              err = fdt_setprop(fdt, nodeoffset,
 -                      "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
 -              if (err < 0)
 -                      printf("WARNING: could not set linux,stdout-path %s.\n",
 -                              fdt_strerror(err));
 -      }
 -#endif
 -
 -      return err;
 +      return fdt_fixup_stdout(fdt, nodeoffset);
  }
  
  void do_fixup_by_path(void *fdt, const char *path, const char *prop,
@@@ -365,31 -344,31 +365,31 @@@ void do_fixup_by_compat_u32(void *fdt, 
  }
  
  /*
 - * Get cells len in bytes
 - *     if #NNNN-cells property is 2 then len is 8
 - *     otherwise len is 4
 + * fdt_pack_reg - pack address and size array into the "reg"-suitable stream
   */
 -static int get_cells_len(void *blob, char *nr_cells_name)
 +static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size,
 +                      int n)
  {
 -      const fdt32_t *cell;
 -
 -      cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
 -      if (cell && fdt32_to_cpu(*cell) == 2)
 -              return 8;
 +      int i;
 +      int address_cells = fdt_address_cells(fdt, 0);
 +      int size_cells = fdt_size_cells(fdt, 0);
 +      char *p = buf;
  
 -      return 4;
 -}
 +      for (i = 0; i < n; i++) {
 +              if (address_cells == 2)
 +                      *(fdt64_t *)p = cpu_to_fdt64(address[i]);
 +              else
 +                      *(fdt32_t *)p = cpu_to_fdt32(address[i]);
 +              p += 4 * address_cells;
  
 -/*
 - * Write a 4 or 8 byte big endian cell
 - */
 -static void write_cell(u8 *addr, u64 val, int size)
 -{
 -      int shift = (size - 1) * 8;
 -      while (size-- > 0) {
 -              *addr++ = (val >> shift) & 0xff;
 -              shift -= 8;
 +              if (size_cells == 2)
 +                      *(fdt64_t *)p = cpu_to_fdt64(size[i]);
 +              else
 +                      *(fdt32_t *)p = cpu_to_fdt32(size[i]);
 +              p += 4 * size_cells;
        }
 +
 +      return p - (char *)buf;
  }
  
  #ifdef CONFIG_NR_DRAM_BANKS
  int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)
  {
        int err, nodeoffset;
 -      int addr_cell_len, size_cell_len, len;
 +      int len;
        u8 tmp[MEMORY_BANKS_MAX * 16]; /* Up to 64-bit address + 64-bit size */
 -      int bank;
  
        if (banks > MEMORY_BANKS_MAX) {
                printf("%s: num banks %d exceeds hardcoded limit %d."
                return err;
        }
  
 -      /* update, or add and update /memory node */
 -      nodeoffset = fdt_path_offset(blob, "/memory");
 -      if (nodeoffset < 0) {
 -              nodeoffset = fdt_add_subnode(blob, 0, "memory");
 -              if (nodeoffset < 0)
 -                      printf("WARNING: could not create /memory: %s.\n",
 -                                      fdt_strerror(nodeoffset));
 -              return nodeoffset;
 -      }
 +      /* find or create "/memory" node. */
 +      nodeoffset = fdt_find_or_add_subnode(blob, 0, "memory");
 +      if (nodeoffset < 0)
 +                      return nodeoffset;
 +
        err = fdt_setprop(blob, nodeoffset, "device_type", "memory",
                        sizeof("memory"));
        if (err < 0) {
                return err;
        }
  
 -      addr_cell_len = get_cells_len(blob, "#address-cells");
 -      size_cell_len = get_cells_len(blob, "#size-cells");
 -
 -      for (bank = 0, len = 0; bank < banks; bank++) {
 -              write_cell(tmp + len, start[bank], addr_cell_len);
 -              len += addr_cell_len;
 -
 -              write_cell(tmp + len, size[bank], size_cell_len);
 -              len += size_cell_len;
 -      }
 +      len = fdt_pack_reg(blob, tmp, start, size, banks);
  
        err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
        if (err < 0) {
@@@ -457,18 -450,8 +457,18 @@@ void fdt_fixup_ethernet(void *fdt
        if (node < 0)
                return;
  
 +      if (!getenv("ethaddr")) {
 +              if (getenv("usbethaddr")) {
 +                      strcpy(mac, "usbethaddr");
 +              } else {
 +                      debug("No ethernet MAC Address defined\n");
 +                      return;
 +              }
 +      } else {
 +              strcpy(mac, "ethaddr");
 +      }
 +
        i = 0;
 -      strcpy(mac, "ethaddr");
        while ((tmp = getenv(mac)) != NULL) {
                sprintf(enet, "ethernet%d", i);
                path = fdt_getprop(fdt, node, enet, NULL);
  }
  
  /* Resize the fdt to its actual size + a bit of padding */
 -int fdt_resize(void *blob)
 +int fdt_shrink_to_minimum(void *blob)
  {
        int i;
        uint64_t addr, size;
        ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
        if (ret < 0)
                return ret;
+       if (getenv("fdtsize"))
+               setenv_hex("fdtsize", actualsize);
        return actualsize;
  }
  
@@@ -783,11 -767,11 +784,11 @@@ int fdt_node_set_part_info(void *blob, 
  
                part = list_entry(pentry, struct part_info, link);
  
 -              debug("%2d: %-20s0x%08x\t0x%08x\t%d\n",
 +              debug("%2d: %-20s0x%08llx\t0x%08llx\t%d\n",
                        part_num, part->name, part->size,
                        part->offset, part->mask_flags);
  
 -              sprintf(buf, "partition@%x", part->offset);
 +              sprintf(buf, "partition@%llx", part->offset);
  add_sub:
                ret = fdt_add_subnode(blob, parent_offset, buf);
                if (ret == -FDT_ERR_NOSPACE) {
@@@ -915,6 -899,17 +916,6 @@@ void fdt_del_node_and_alias(void *blob
        fdt_delprop(blob, off, alias);
  }
  
 -/* Helper to read a big number; size is in cells (not bytes) */
 -static inline u64 of_read_number(const fdt32_t *cell, int size)
 -{
 -      u64 r = 0;
 -      while (size--)
 -              r = (r << 32) | fdt32_to_cpu(*(cell++));
 -      return r;
 -}
 -
 -#define PRu64 "%llx"
 -
  /* Max address size we deal with */
  #define OF_MAX_ADDR_CELLS     4
  #define OF_BAD_ADDR   ((u64)-1)
@@@ -946,13 -941,18 +947,13 @@@ struct of_bus 
  };
  
  /* Default translator (generic bus) */
 -static void of_bus_default_count_cells(void *blob, int parentoffset,
 +void of_bus_default_count_cells(void *blob, int parentoffset,
                                        int *addrc, int *sizec)
  {
        const fdt32_t *prop;
  
 -      if (addrc) {
 -              prop = fdt_getprop(blob, parentoffset, "#address-cells", NULL);
 -              if (prop)
 -                      *addrc = be32_to_cpup(prop);
 -              else
 -                      *addrc = 2;
 -      }
 +      if (addrc)
 +              *addrc = fdt_address_cells(blob, parentoffset);
  
        if (sizec) {
                prop = fdt_getprop(blob, parentoffset, "#size-cells", NULL);
@@@ -972,8 -972,8 +973,8 @@@ static u64 of_bus_default_map(fdt32_t *
        s  = of_read_number(range + na + pna, ns);
        da = of_read_number(addr, na);
  
 -      debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
 -          cp, s, da);
 +      debug("OF: default map, cp=%" PRIu64 ", s=%" PRIu64
 +            ", da=%" PRIu64 "\n", cp, s, da);
  
        if (da < cp || da >= (cp + s))
                return OF_BAD_ADDR;
@@@ -1051,7 -1051,7 +1052,7 @@@ static int of_translate_one(void * blob
  
   finish:
        of_dump_addr("OF: parent translation for:", addr, pna);
 -      debug("OF: with offset: "PRu64"\n", offset);
 +      debug("OF: with offset: %" PRIu64 "\n", offset);
  
        /* Translate it into parent bus space */
        return pbus->translate(addr, offset, pna);
@@@ -1085,7 -1085,7 +1086,7 @@@ static u64 __of_translate_address(void 
                goto bail;
        bus = &of_busses[0];
  
-       /* Cound address cells & copy address locally */
+       /* Count address cells & copy address locally */
        bus->count_cells(blob, parent, &na, &ns);
        if (!OF_CHECK_COUNTS(na, ns)) {
                printf("%s: Bad cell count for %s\n", __FUNCTION__,
@@@ -1177,8 -1177,7 +1178,8 @@@ int fdt_node_offset_by_compat_reg(void 
   */
  int fdt_alloc_phandle(void *blob)
  {
 -      int offset, phandle = 0;
 +      int offset;
 +      uint32_t phandle = 0;
  
        for (offset = fdt_next_node(blob, -1, NULL); offset >= 0;
             offset = fdt_next_node(blob, offset, NULL)) {
@@@ -1380,9 -1379,9 +1381,9 @@@ int fdt_verify_alias_address(void *fdt
  
        dt_addr = fdt_translate_address(fdt, node, reg);
        if (addr != dt_addr) {
 -              printf("Warning: U-Boot configured device %s at address %llx,\n"
 -                     " but the device tree has it address %llx.\n",
 -                     alias, addr, dt_addr);
 +              printf("Warning: U-Boot configured device %s at address %"
 +                     PRIx64 ",\n but the device tree has it address %"
 +                     PRIx64 ".\n", alias, addr, dt_addr);
                return 0;
        }
  
@@@ -1398,165 -1397,13 +1399,165 @@@ u64 fdt_get_base_address(void *fdt, in
        u32 naddr;
        const fdt32_t *prop;
  
 -      prop = fdt_getprop(fdt, node, "#address-cells", &size);
 -      if (prop && size == 4)
 -              naddr = be32_to_cpup(prop);
 -      else
 -              naddr = 2;
 +      naddr = fdt_address_cells(fdt, node);
  
        prop = fdt_getprop(fdt, node, "ranges", &size);
  
        return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0;
  }
 +
 +/*
 + * Read a property of size <prop_len>. Currently only supports 1 or 2 cells.
 + */
 +static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off,
 +                       uint64_t *val, int cells)
 +{
 +      const fdt32_t *prop32 = &prop[cell_off];
 +      const fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off];
 +
 +      if ((cell_off + cells) > prop_len)
 +              return -FDT_ERR_NOSPACE;
 +
 +      switch (cells) {
 +      case 1:
 +              *val = fdt32_to_cpu(*prop32);
 +              break;
 +      case 2:
 +              *val = fdt64_to_cpu(*prop64);
 +              break;
 +      default:
 +              return -FDT_ERR_NOSPACE;
 +      }
 +
 +      return 0;
 +}
 +
 +/**
 + * fdt_read_range - Read a node's n'th range property
 + *
 + * @fdt: ptr to device tree
 + * @node: offset of node
 + * @n: range index
 + * @child_addr: pointer to storage for the "child address" field
 + * @addr: pointer to storage for the CPU view translated physical start
 + * @len: pointer to storage for the range length
 + *
 + * Convenience function that reads and interprets a specific range out of
 + * a number of the "ranges" property array.
 + */
 +int fdt_read_range(void *fdt, int node, int n, uint64_t *child_addr,
 +                 uint64_t *addr, uint64_t *len)
 +{
 +      int pnode = fdt_parent_offset(fdt, node);
 +      const fdt32_t *ranges;
 +      int pacells;
 +      int acells;
 +      int scells;
 +      int ranges_len;
 +      int cell = 0;
 +      int r = 0;
 +
 +      /*
 +       * The "ranges" property is an array of
 +       * { <child address> <parent address> <size in child address space> }
 +       *
 +       * All 3 elements can span a diffent number of cells. Fetch their size.
 +       */
 +      pacells = fdt_getprop_u32_default_node(fdt, pnode, 0, "#address-cells", 1);
 +      acells = fdt_getprop_u32_default_node(fdt, node, 0, "#address-cells", 1);
 +      scells = fdt_getprop_u32_default_node(fdt, node, 0, "#size-cells", 1);
 +
 +      /* Now try to get the ranges property */
 +      ranges = fdt_getprop(fdt, node, "ranges", &ranges_len);
 +      if (!ranges)
 +              return -FDT_ERR_NOTFOUND;
 +      ranges_len /= sizeof(uint32_t);
 +
 +      /* Jump to the n'th entry */
 +      cell = n * (pacells + acells + scells);
 +
 +      /* Read <child address> */
 +      if (child_addr) {
 +              r = fdt_read_prop(ranges, ranges_len, cell, child_addr,
 +                                acells);
 +              if (r)
 +                      return r;
 +      }
 +      cell += acells;
 +
 +      /* Read <parent address> */
 +      if (addr)
 +              *addr = fdt_translate_address(fdt, node, ranges + cell);
 +      cell += pacells;
 +
 +      /* Read <size in child address space> */
 +      if (len) {
 +              r = fdt_read_prop(ranges, ranges_len, cell, len, scells);
 +              if (r)
 +                      return r;
 +      }
 +
 +      return 0;
 +}
 +
 +/**
 + * fdt_setup_simplefb_node - Fill and enable a simplefb node
 + *
 + * @fdt: ptr to device tree
 + * @node: offset of the simplefb node
 + * @base_address: framebuffer base address
 + * @width: width in pixels
 + * @height: height in pixels
 + * @stride: bytes per line
 + * @format: pixel format string
 + *
 + * Convenience function to fill and enable a simplefb node.
 + */
 +int fdt_setup_simplefb_node(void *fdt, int node, u64 base_address, u32 width,
 +                          u32 height, u32 stride, const char *format)
 +{
 +      char name[32];
 +      fdt32_t cells[4];
 +      int i, addrc, sizec, ret;
 +
 +      of_bus_default_count_cells(fdt, fdt_parent_offset(fdt, node),
 +                                 &addrc, &sizec);
 +      i = 0;
 +      if (addrc == 2)
 +              cells[i++] = cpu_to_fdt32(base_address >> 32);
 +      cells[i++] = cpu_to_fdt32(base_address);
 +      if (sizec == 2)
 +              cells[i++] = 0;
 +      cells[i++] = cpu_to_fdt32(height * stride);
 +
 +      ret = fdt_setprop(fdt, node, "reg", cells, sizeof(cells[0]) * i);
 +      if (ret < 0)
 +              return ret;
 +
 +      snprintf(name, sizeof(name), "framebuffer@%llx", base_address);
 +      ret = fdt_set_name(fdt, node, name);
 +      if (ret < 0)
 +              return ret;
 +
 +      ret = fdt_setprop_u32(fdt, node, "width", width);
 +      if (ret < 0)
 +              return ret;
 +
 +      ret = fdt_setprop_u32(fdt, node, "height", height);
 +      if (ret < 0)
 +              return ret;
 +
 +      ret = fdt_setprop_u32(fdt, node, "stride", stride);
 +      if (ret < 0)
 +              return ret;
 +
 +      ret = fdt_setprop_string(fdt, node, "format", format);
 +      if (ret < 0)
 +              return ret;
 +
 +      ret = fdt_setprop_string(fdt, node, "status", "okay");
 +      if (ret < 0)
 +              return ret;
 +
 +      return 0;
 +}
diff --combined common/lcd.c
index 3ed504df50df128180211a39186b55f85074de97,36a41056f60b5976fb67c08d982d85c93fdca4fe..5ac4fd697c73a95bc82ad014c2a26af8cb5802a0
@@@ -4,7 -4,7 +4,7 @@@
   * (C) Copyright 2001-2002
   * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  /************************************************************************/
  #endif
  #include <lcd.h>
  #include <watchdog.h>
 -
 +#include <asm/unaligned.h>
  #include <splash.h>
 +#include <asm/io.h>
 +#include <asm/unaligned.h>
 +#include <fdt_support.h>
  
  #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
        defined(CONFIG_CPU_MONAHANS)
 -#define CONFIG_CPU_PXA
  #include <asm/byteorder.h>
  #endif
  
@@@ -53,6 -51,7 +53,6 @@@
  /* ** FONT DATA                                                               */
  /************************************************************************/
  #include <video_font.h>               /* Get font data, width and height      */
 -#include <video_font_data.h>
  
  /************************************************************************/
  /* ** LOGO DATA                                                               */
  #ifdef CONFIG_LCD_LOGO
  # include <bmp_logo.h>                /* Get logo data, width and height      */
  # include <bmp_logo_data.h>
- # if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
+ # if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP < LCD_COLOR16)
  #  error Default Color Map overlaps with Logo Color Map
  # endif
  #endif
  
 +#ifdef CONFIG_SANDBOX
 +#include <asm/sdl.h>
 +#endif
 +
  #ifndef CONFIG_LCD_ALIGNMENT
  #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
  #endif
  #if LCD_BPP == LCD_MONOCHROME
  # define COLOR_MASK(c)                ((c)      | (c) << 1 | (c) << 2 | (c) << 3 | \
                                 (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
 -#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR24)
 +#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
 +      (LCD_BPP == LCD_COLOR32)
  # define COLOR_MASK(c)                (c)
  #else
  # error Unsupported LCD BPP.
  DECLARE_GLOBAL_DATA_PTR;
  
  static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
 -static inline void lcd_puts_xy(ushort x, ushort y, uchar *s);
  static inline void lcd_putc_xy(ushort x, ushort y, uchar  c);
  
  static int lcd_init(void *lcdbase);
  
  static void *lcd_logo(void);
  
 -static int lcd_getbgcolor(void);
  static void lcd_setfgcolor(int color);
  static void lcd_setbgcolor(int color);
  
@@@ -149,13 -145,6 +149,13 @@@ void lcd_sync(void
        if (lcd_flush_dcache)
                flush_dcache_range((u32)lcd_base,
                        (u32)(lcd_base + lcd_get_size(&line_length)));
 +#elif defined(CONFIG_SANDBOX) && defined(CONFIG_VIDEO_SANDBOX_SDL)
 +      static ulong last_sync;
 +
 +      if (get_timer(last_sync) > 10) {
 +              sandbox_sdl_sync(lcd_base);
 +              last_sync = get_timer(0);
 +      }
  #endif
  }
  
@@@ -176,20 -165,10 +176,20 @@@ static void console_scrollup(void
               CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
  
        /* Clear the last rows */
 +#if (LCD_BPP != LCD_COLOR32)
        memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
                COLOR_MASK(lcd_color_bg),
                CONSOLE_ROW_SIZE * rows);
 -
 +#else
 +      u32 *ppix = lcd_console_address +
 +                  CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
 +      u32 i;
 +      for (i = 0;
 +          i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
 +          i++) {
 +              *ppix++ = COLOR_MASK(lcd_color_bg);
 +      }
 +#endif
        lcd_sync();
        console_row -= rows;
  }
@@@ -223,11 -202,6 +223,11 @@@ static inline void console_newline(void
  
  /*----------------------------------------------------------------------*/
  
 +static void lcd_stub_putc(struct stdio_dev *dev, const char c)
 +{
 +      lcd_putc(c);
 +}
 +
  void lcd_putc(const char c)
  {
        if (!lcd_is_enabled) {
  
  /*----------------------------------------------------------------------*/
  
 +static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
 +{
 +      lcd_puts(s);
 +}
 +
  void lcd_puts(const char *s)
  {
        if (!lcd_is_enabled) {
@@@ -306,7 -275,7 +306,7 @@@ void lcd_printf(const char *fmt, ...
  
  static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
  {
-       uchar *dest;
+       void *dest;
        ushort row;
  
  #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
  #endif
  
  #if LCD_BPP == LCD_MONOCHROME
--      ushort off  = x * (1 << LCD_BPP) % 8;
++      ushort off  = x * NBITS(LCD_BPP) % 8;
  #endif
  
-       dest = (uchar *)(lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP)/8);
 -      dest = lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8;
++      dest = lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP) / 8;
  
        for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
                uchar *s = str;
                int i;
 -#if LCD_BPP == LCD_COLOR24
 -              ulong *d = dest;
 -#elif LCD_BPP == LCD_COLOR16
 -              ushort *d = dest;
 +#if LCD_BPP == LCD_COLOR16
 +              ushort *d = (ushort *)dest;
 +#elif LCD_BPP == LCD_COLOR32
 +              u32 *d = (u32 *)dest;
  #else
                uchar *d = dest;
  #endif
  
                        *d++ = rest | (sym >> off);
                        rest = sym << (8-off);
- #elif LCD_BPP == LCD_COLOR8
-                       for (c = 0; c < 8; ++c) {
-                               *d++ = (bits & 0x80) ?
-                                               lcd_color_fg : lcd_color_bg;
-                               bits <<= 1;
-                       }
- #elif LCD_BPP == LCD_COLOR16
-                       for (c = 0; c < 8; ++c) {
-                               *d++ = (bits & 0x80) ?
-                                               lcd_color_fg : lcd_color_bg;
-                               bits <<= 1;
-                       }
- #elif LCD_BPP == LCD_COLOR32
+ #else
                        for (c = 0; c < 8; ++c) {
                                *d++ = (bits & 0x80) ?
                                                lcd_color_fg : lcd_color_bg;
        }
  }
  
 -/*----------------------------------------------------------------------*/
 -
 -static inline void lcd_puts_xy(ushort x, ushort y, uchar *s)
 -{
 -      lcd_drawchars(x, y, s, strlen((char *)s));
 -}
 -
 -/*----------------------------------------------------------------------*/
 -
  static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
  {
        lcd_drawchars(x, y, &c, 1);
@@@ -390,6 -356,16 +378,16 @@@ static int test_colors[N_BLK_HOR * N_BL
        CONSOLE_COLOR_BLUE,     CONSOLE_COLOR_MAGENTA,  CONSOLE_COLOR_CYAN,
  };
  
 -#elif LCD_BPP == LCD_COLOR24
+ #if LCD_BPP == LCD_COLOR8
+ typedef uchar pix_t;
+ #elif LCD_BPP == LCD_COLOR16
+ typedef ushort pix_t;
++#elif LCD_BPP == LCD_COLOR32
+ typedef ulong pix_t;
+ #else
+ #error Unsupported pixelformat
+ #endif
  static void test_pattern(void)
  {
        ushort v_max  = panel_info.vl_row;
        ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
        ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
        ushort v, h;
-       uchar *pix = (uchar *)lcd_base;
+       pix_t *pix = lcd_base;
  
        printf("[LCD] Test Pattern: %d x %d [%d x %d]\n",
                h_max, v_max, h_step, v_step);
  /************************************************************************/
  /* ** GENERIC Initialization Routines                                 */
  /************************************************************************/
 -
 -int lcd_get_size(int *line_length)
 +/*
 + * With most lcd drivers the line length is set up
 + * by calculating it from panel_info parameters. Some
 + * drivers need to calculate the line length differently,
 + * so make the function weak to allow overriding it.
 + */
 +__weak int lcd_get_size(int *line_length)
  {
        *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
        return *line_length * panel_info.vl_row;
@@@ -434,7 -405,7 +432,7 @@@ int drv_lcd_init(void
        struct stdio_dev lcddev;
        int rc;
  
 -      lcd_base = (void *)gd->fb_base;
 +      lcd_base = map_sysmem(gd->fb_base, 0);
  
        lcd_init(lcd_base);             /* LCD initialization */
  
        strcpy(lcddev.name, "lcd");
        lcddev.ext   = 0;                       /* No extensions */
        lcddev.flags = DEV_FLAGS_OUTPUT;        /* Output only */
 -      lcddev.putc  = lcd_putc;                /* 'putc' function */
 -      lcddev.puts  = lcd_puts;                /* 'puts' function */
 +      lcddev.putc  = lcd_stub_putc;           /* 'putc' function */
 +      lcddev.puts  = lcd_stub_puts;           /* 'puts' function */
  
        rc = stdio_register(&lcddev);
  
@@@ -484,22 -455,12 +482,22 @@@ void lcd_clear(void
        test_pattern();
  #else
        /* set framebuffer to background color */
 +#if (LCD_BPP != LCD_COLOR32)
        memset((char *)lcd_base,
 -              COLOR_MASK(lcd_getbgcolor()),
 +              COLOR_MASK(lcd_color_bg),
                lcd_line_length * panel_info.vl_row);
 +#else
 +      u32 *ppix = lcd_base;
 +      u32 i;
 +      for (i = 0;
 +         i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
 +         i++) {
 +              *ppix++ = COLOR_MASK(lcd_color_bg);
 +      }
 +#endif
  #endif
        /* Paint the logo and retrieve LCD base address */
-       debug("[LCD] Drawing the logo...\n");
+       debug("[LCD] Drawing the logo @ %p...\n", lcd_base);
        lcd_console_address = lcd_logo();
  
        console_col = 0;
@@@ -525,22 -486,25 +523,24 @@@ U_BOOT_CMD
  static int lcd_init(void *lcdbase)
  {
        /* Initialize the lcd controller */
-       debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
+       debug("[LCD] Initializing %ux%ux%u LCD framebuffer at %p\n",
+               panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix),
+               lcdbase);
  
        lcd_ctrl_init(lcdbase);
  
        /*
 -       * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores
 +       * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi) ignores
         * the 'lcdbase' argument and uses custom lcd base address
         * by setting up gd->fb_base. Check for this condition and fixup
         * 'lcd_base' address.
         */
 -      if ((unsigned long)lcdbase != gd->fb_base)
 -              lcd_base = (void *)gd->fb_base;
 +      if (map_to_sysmem(lcdbase) != gd->fb_base)
 +              lcd_base = map_sysmem(gd->fb_base, 0);
  
        debug("[LCD] Using LCD frambuffer at %p\n", lcd_base);
  
        lcd_get_size(&lcd_line_length);
 -      lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
        lcd_is_enabled = 1;
        lcd_clear();
        lcd_enable();
@@@ -604,6 -568,20 +604,6 @@@ static void lcd_setbgcolor(int color
        lcd_color_bg = color;
  }
  
 -/*----------------------------------------------------------------------*/
 -
 -int lcd_getfgcolor(void)
 -{
 -      return lcd_color_fg;
 -}
 -
 -/*----------------------------------------------------------------------*/
 -
 -static inline int lcd_getbgcolor(void)
 -{
 -      return lcd_color_bg;
 -}
 -
  /************************************************************************/
  /* ** Chipset depending Bitmap / Logo stuff...                          */
  /************************************************************************/
@@@ -613,7 -591,7 +613,7 @@@ static inline ushort *configuration_get
        struct pxafb_info *fbi = &panel_info.pxa;
        return (ushort *)fbi->palette;
  #elif defined(CONFIG_MPC823)
-       immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
        cpm8xx_t *cp = &(immr->im_cpm);
        return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
  #elif defined(CONFIG_ATMEL_LCD)
@@@ -640,7 -618,7 +640,7 @@@ void bitmap_plot(int x, int y
        uchar *fb;
        ushort *fb16;
  #if defined(CONFIG_MPC823)
-       immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
        cpm8xx_t *cp = &(immr->im_cpm);
  #endif
        unsigned bpix = NBITS(panel_info.vl_bpix);
                        bmap += BMP_LOGO_WIDTH;
                        fb += panel_info.vl_col;
                }
-       }
-       else { /* true color mode */
+       } else if (NBITS(panel_info.vl_bpix) == 16) {
                u16 col16;
                fb16 = (ushort *)fb;
                for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
                        bmap += BMP_LOGO_WIDTH;
                        fb16 += panel_info.vl_col;
                }
+       } else { /* true color mode */
+               u16 col16;
+               u32 *fb32 = lcd_base + y * lcd_line_length + x;
+               for (i = 0; i < BMP_LOGO_HEIGHT; i++) {
+                       for (j = 0; j < BMP_LOGO_WIDTH; j++) {
+                               col16 = bmp_logo_palette[bmap[j] - 16];
+                               fb32[j] =
+                                       ((col16 & 0x000F) << 4) |
+                                       ((col16 & 0x00F0) << 8) |
+                                       ((col16 & 0x0F00) << 12);
+                               }
+                       bmap += BMP_LOGO_WIDTH;
+                       fb32 += panel_info.vl_col;
+               }
        }
  
        WATCHDOG_RESET();
@@@ -747,7 -739,7 +761,7 @@@ static void splash_align_axis(int *axis
        else
                return;
  
 -      *axis = max(0, axis_alignment);
 +      *axis = max(0, (int)axis_alignment);
  }
  #endif
  
@@@ -804,9 -796,9 +818,9 @@@ static void lcd_display_rle8_bitmap(bmp
        int x, y;
        int decode = 1;
  
 -      width = le32_to_cpu(bmp->header.width);
 -      height = le32_to_cpu(bmp->header.height);
 -      bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
 +      width = get_unaligned_le32(&bmp->header.width);
 +      height = get_unaligned_le32(&bmp->header.height);
 +      bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
  
        x = 0;
        y = height - 1;
  }
  #endif
  
 -#if defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
 +#if defined(CONFIG_MPC823)
  #define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++)
  #else
  #define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++
@@@ -905,18 -897,28 +919,26 @@@ static inline void fb_put_word(uchar **
  #endif
  #endif /* CONFIG_BMP_16BPP */
  
+ static inline bmp_color_table_entry_t *get_color_table(bmp_image_t *bmp)
+ {
+       bmp_header_t *bh = &bmp->header;
+       return (void *)bmp + offsetof(bmp_header_t, size) + bh->size;
+ }
  int lcd_display_bitmap(ulong bmp_image, int x, int y)
  {
 -#if !defined(CONFIG_MCC200)
        ushort *cmap = NULL;
 -#endif
        ushort *cmap_base = NULL;
        ushort i, j;
        uchar *fb;
 -      bmp_image_t *bmp=(bmp_image_t *)bmp_image;
 +      bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
        uchar *bmap;
        ushort padded_width;
-       unsigned long width, height, byte_width;
+       unsigned long width, height;
        unsigned long pwidth = panel_info.vl_col;
-       unsigned colors, bpix, bmp_bpix;
+       unsigned long long colors;
+       unsigned bpix, bmp_bpix;
+       bmp_color_table_entry_t *cte;
  
        if (!bmp || !(bmp->header.signature[0] == 'B' &&
                bmp->header.signature[1] == 'M')) {
                return 1;
        }
  
 -      width = le32_to_cpu(bmp->header.width);
 -      height = le32_to_cpu(bmp->header.height);
 -      bmp_bpix = le16_to_cpu(bmp->header.bit_count);
 -      colors = 1ULL << bmp_bpix;
 +      width = get_unaligned_le32(&bmp->header.width);
 +      height = get_unaligned_le32(&bmp->header.height);
 +      bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
 +
 +      colors = 1 << bmp_bpix;
  
        bpix = NBITS(panel_info.vl_bpix);
  
                return 1;
        }
  
 -      /* We support displaying 8bpp BMPs on 16bpp or 32bpp LCDs */
 -      if (bpix != bmp_bpix && (bmp_bpix != 8 || (bpix != 16 && bpix != 32))) {
 +      /*
 +       * We support displaying 8bpp BMPs on 16bpp LCDs
 +       * and displaying 24bpp BMPs on 32bpp LCDs
 +       * */
 +      if (bpix != bmp_bpix &&
 +          !(bmp_bpix == 8 && bpix == 16) &&
 +          !(bmp_bpix == 24 && bpix == 32)) {
                printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
 -                      bpix,
 -                      le16_to_cpu(bmp->header.bit_count));
 -
 +                      bpix, get_unaligned_le16(&bmp->header.bit_count));
                return 1;
        }
  
-       debug("Display-bmp: %d x %d  with %d colors\n",
-               (int)width, (int)height, (int)colors);
+       debug("Display-bmp: %lu x %lu  with %llu colors\n",
+               width, height, colors);
  
 -#if !defined(CONFIG_MCC200)
 -      /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */
+       cte = get_color_table(bmp);
        if (bmp_bpix == 8) {
                cmap = configuration_get_cmap();
                cmap_base = cmap;
  
                /* Set color map */
                for (i = 0; i < colors; ++i) {
-                       bmp_color_table_entry_t cte = bmp->color_table[i];
  #if !defined(CONFIG_ATMEL_LCD)
                        ushort colreg =
-                               ( ((cte.red)   << 8) & 0xf800) |
-                               ( ((cte.green) << 3) & 0x07e0) |
-                               ( ((cte.blue)  >> 3) & 0x001f) ;
+                               ( ((cte[i].red)   << 8) & 0xf800) |
+                               ( ((cte[i].green) << 3) & 0x07e0) |
+                               ( ((cte[i].blue)  >> 3) & 0x001f) ;
  #ifdef CONFIG_SYS_INVERT_COLORS
                        *cmap = 0xffff - colreg;
  #else
                        cmap++;
  #endif
  #else /* CONFIG_ATMEL_LCD */
-                       lcd_setcolreg(i, cte.red, cte.green, cte.blue);
+                       lcd_setcolreg(i, cte[i].red, cte[i].green, cte[i].blue);
  #endif
                }
        }
 -#endif
 -
 -      /*
 -       *  BMP format for Monochrome assumes that the state of a
 -       * pixel is described on a per Bit basis, not per Byte.
 -       *  So, in case of Monochrome BMP we should align widths
 -       * on a byte boundary and convert them from Bit to Byte
 -       * units.
 -       *  Probably, PXA250 and MPC823 process 1bpp BMP images in
 -       * their own ways, so make the converting to be MCC200
 -       * specific.
 -       */
 -#if defined(CONFIG_MCC200)
 -      if (bpix == 1) {
 -              width = ALIGN(width, 8) >> 3;
 -              x     = ALIGN(x, 8) >> 3;
 -              pwidth= ALIGN(pwidth, 8) >> 3;
 -      }
 -#endif
  
-       padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
+       padded_width = ALIGN(width, 4);
  
  #ifdef CONFIG_SPLASH_SCREEN_ALIGN
        splash_align_axis(&x, pwidth, width);
        splash_align_axis(&y, panel_info.vl_row, height);
  #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
 -      bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
++      bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
  
        if ((x + width) > pwidth)
                width = pwidth - x;
-       if ((y + height) > panel_info.vl_row)
+       if ((y + height) > panel_info.vl_row) {
                height = panel_info.vl_row - y;
+               bmap += (panel_info.vl_row - y) * padded_width;
+       }
  
-       bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
        fb   = (uchar *)(lcd_base +
                (y + height - 1) * lcd_line_length + x * bpix / 8);
  
        switch (bmp_bpix) {
        case 1: /* pass through */
 -      case 8:
 +      case 8: {
  #ifdef CONFIG_LCD_BMP_RLE8
 -              if (le32_to_cpu(bmp->header.compression) == BMP_BI_RLE8) {
 +              u32 compression = get_unaligned_le32(&bmp->header.compression);
 +              if (compression == BMP_BI_RLE8) {
                        if (bpix != 16) {
                                /* TODO implement render code for bpix != 16 */
                                printf("Error: only support 16 bpix");
                }
  #endif
  
-               if (bpix != 16)
-                       byte_width = width;
-               else
-                       byte_width = width * 2;
                for (i = 0; i < height; ++i) {
                        WATCHDOG_RESET();
                        for (j = 0; j < width; j++) {
-                               if (bpix != 16) {
-                                       FB_PUT_BYTE(fb, bmap);
-                               } else {
+                               if (bpix == 32) {
+                                       int i = *bmap++;
+                                       fb[3] = 0; /* T */
+                                       fb[0] = cte[i].blue;
+                                       fb[1] = cte[i].green;
+                                       fb[2] = cte[i].red;
+                                       fb += sizeof(uint32_t) / sizeof(*fb);
+                               } else if (bpix == 16) {
                                        *(uint16_t *)fb = cmap_base[*(bmap++)];
                                        fb += sizeof(uint16_t) / sizeof(*fb);
+                               } else {
+                                       FB_PUT_BYTE(fb, bmap);
                                }
                        }
-                       bmap += (padded_width - width);
-                       fb -= byte_width + lcd_line_length;
+                       if (bpix > 8) {
+                               bmap += padded_width - width;
+                               fb   -= width * bpix / 8 + lcd_line_length;
+                       } else {
+                               bmap += padded_width;
+                               fb -= lcd_line_length;
+                       }
                }
                break;
 -
 +      }
  #if defined(CONFIG_BMP_16BPP)
        case 16:
                for (i = 0; i < height; ++i) {
                }
                break;
  #endif /* CONFIG_BMP_16BPP */
- #endif /* CONFIG_BMP_24BMP */
 +#if defined(CONFIG_BMP_24BMP)
 +      case 24:
 +              for (i = 0; i < height; ++i) {
 +                      for (j = 0; j < width; j++) {
 +                              *(fb++) = *(bmap++);
 +                              *(fb++) = *(bmap++);
 +                              *(fb++) = *(bmap++);
 +                              *(fb++) = 0;
 +                      }
 +                      fb -= lcd_line_length + width * (bpix / 8);
 +              }
 +              break;
++#endif /* CONFIG_BMP_24BPP */
 +#if defined(CONFIG_BMP_32BPP)
        case 32:
                for (i = 0; i < height; ++i) {
+                       WATCHDOG_RESET();
                        for (j = 0; j < width; j++) {
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
+                               fb[3] = *bmap++; /* T */
+                               fb[0] = *bmap++; /* B */
+                               fb[1] = *bmap++; /* G */
+                               fb[2] = *bmap++; /* R */
+                               fb += 4;
                        }
+                       bmap += (padded_width - width) * 4;
                        fb -= lcd_line_length + width * (bpix / 8);
                }
                break;
-       default:
-               break;
 +#endif /* CONFIG_BMP_32BPP */
        };
  
-       lcd_sync();
        return 0;
  }
  #endif
@@@ -1091,12 -1104,16 +1123,16 @@@ static void *lcd_logo(void
  
        if (do_splash && (s = getenv("splashimage")) != NULL) {
                int x = 0, y = 0;
+               char *end;
                do_splash = 0;
  
                if (splash_screen_prepare())
                        return (void *)lcd_base;
  
-               addr = simple_strtoul (s, NULL, 16);
+               addr = simple_strtoul (s, &end, 16);
+               if (addr == 0 || *end != '\0')
+                       return lcd_base;
  
                splash_get_pos(&x, &y);
  
  #endif /* CONFIG_LCD_INFO */
  
  #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
-       return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
+       return lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
  #else
-       return (void *)lcd_base;
- #endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
+       return lcd_base;
+ #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
  }
  
  #ifdef CONFIG_SPLASHIMAGE_GUARD
@@@ -1146,8 -1163,8 +1182,8 @@@ U_BOOT_ENV_CALLBACK(splashimage, on_spl
  
  void lcd_position_cursor(unsigned col, unsigned row)
  {
 -      console_col = min(col, CONSOLE_COLS - 1);
 -      console_row = min(row, CONSOLE_ROWS - 1);
 +      console_col = min_t(short, col, CONSOLE_COLS - 1);
 +      console_row = min_t(short, row, CONSOLE_ROWS - 1);
  }
  
  int lcd_get_pixel_width(void)
@@@ -1173,13 -1190,51 +1209,13 @@@ int lcd_get_screen_columns(void
  #if defined(CONFIG_LCD_DT_SIMPLEFB)
  static int lcd_dt_simplefb_configure_node(void *blob, int off)
  {
 -      u32 stride;
 -      fdt32_t cells[2];
 -      int ret;
 -      static const char format[] =
  #if LCD_BPP == LCD_COLOR16
 -              "r5g6b5";
 +      return fdt_setup_simplefb_node(blob, off, gd->fb_base,
 +                                     panel_info.vl_col, panel_info.vl_row,
 +                                     panel_info.vl_col * 2, "r5g6b5");
  #else
 -              "";
 +      return -1;
  #endif
 -
 -      if (!format[0])
 -              return -1;
 -
 -      stride = panel_info.vl_col * 2;
 -
 -      cells[0] = cpu_to_fdt32(gd->fb_base);
 -      cells[1] = cpu_to_fdt32(stride * panel_info.vl_row);
 -      ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2);
 -      if (ret < 0)
 -              return -1;
 -
 -      cells[0] = cpu_to_fdt32(panel_info.vl_col);
 -      ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0]));
 -      if (ret < 0)
 -              return -1;
 -
 -      cells[0] = cpu_to_fdt32(panel_info.vl_row);
 -      ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0]));
 -      if (ret < 0)
 -              return -1;
 -
 -      cells[0] = cpu_to_fdt32(stride);
 -      ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0]));
 -      if (ret < 0)
 -              return -1;
 -
 -      ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1);
 -      if (ret < 0)
 -              return -1;
 -
 -      ret = fdt_delprop(blob, off, "status");
 -      if (ret < 0)
 -              return -1;
 -
 -      return 0;
  }
  
  int lcd_dt_simplefb_add_node(void *blob)
diff --combined common/spl/spl.c
index 1826c47a99c464bd0023f3c173cab788de49acb0,e9e3c7449f1337ccb67f111225d8cbcf7f084a92..46447f4905216bb98748794d07752ea8c8121483
@@@ -7,7 -7,6 +7,7 @@@
   * SPDX-License-Identifier:   GPL-2.0+
   */
  #include <common.h>
 +#include <dm.h>
  #include <spl.h>
  #include <asm/u-boot.h>
  #include <nand.h>
@@@ -16,7 -15,6 +16,7 @@@
  #include <i2c.h>
  #include <image.h>
  #include <malloc.h>
 +#include <dm/root.h>
  #include <linux/compiler.h>
  
  DECLARE_GLOBAL_DATA_PTR;
@@@ -25,7 -23,6 +25,7 @@@
  #define CONFIG_SYS_UBOOT_START        CONFIG_SYS_TEXT_BASE
  #endif
  #ifndef CONFIG_SYS_MONITOR_LEN
 +/* Unknown U-Boot size, let's assume it will not be more than 200 KB */
  #define CONFIG_SYS_MONITOR_LEN        (200 * 1024)
  #endif
  
@@@ -64,15 -61,6 +64,15 @@@ __weak void spl_board_prepare_for_linux
        /* Nothing to do! */
  }
  
 +void spl_set_header_raw_uboot(void)
 +{
 +      spl_image.size = CONFIG_SYS_MONITOR_LEN;
 +      spl_image.entry_point = CONFIG_SYS_UBOOT_START;
 +      spl_image.load_addr = CONFIG_SYS_TEXT_BASE;
 +      spl_image.os = IH_OS_U_BOOT;
 +      spl_image.name = "U-Boot";
 +}
 +
  void spl_parse_image_header(const struct image_header *header)
  {
        u32 header_size = sizeof(struct image_header);
                }
                spl_image.os = image_get_os(header);
                spl_image.name = image_get_name(header);
 -              debug("spl: payload image: %s load addr: 0x%x size: %d\n",
 -                      spl_image.name, spl_image.load_addr, spl_image.size);
 +              debug("spl: payload image: %.*s load addr: 0x%x size: %d\n",
 +                      (int)sizeof(spl_image.name), spl_image.name,
 +                      spl_image.load_addr, spl_image.size);
        } else {
                /* Signature not found - assume u-boot.bin */
                debug("mkimage signature not found - ih_magic = %x\n",
                        header->ih_magic);
 -              /* Let's assume U-Boot will not be more than 200 KB */
 -              spl_image.size = CONFIG_SYS_MONITOR_LEN;
 -              spl_image.entry_point = CONFIG_SYS_UBOOT_START;
 -              spl_image.load_addr = CONFIG_SYS_TEXT_BASE;
 -              spl_image.os = IH_OS_U_BOOT;
 -              spl_image.name = "U-Boot";
 +              spl_set_header_raw_uboot();
        }
  }
  
@@@ -141,16 -133,9 +141,16 @@@ void board_init_r(gd_t *dummy1, ulong d
        u32 boot_device;
        debug(">>spl:board_init_r()\n");
  
 -#ifdef CONFIG_SYS_SPL_MALLOC_START
 +#if defined(CONFIG_SYS_SPL_MALLOC_START)
        mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
                        CONFIG_SYS_SPL_MALLOC_SIZE);
 +      gd->flags |= GD_FLG_FULL_MALLOC_INIT;
 +#elif defined(CONFIG_SYS_MALLOC_F_LEN)
 +      gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN;
 +      gd->malloc_ptr = 0;
 +#endif
 +#ifdef CONFIG_SPL_DM
 +      dm_init_and_scan(true);
  #endif
  
  #ifndef CONFIG_PPC
  #endif
  #ifdef CONFIG_SPL_NAND_SUPPORT
        case BOOT_DEVICE_NAND:
-               spl_nand_load_image();
-               break;
+               if (spl_nand_load_image() == 0)
+                       break;
+               /* fallthru in case of failure to activate ymodem download */
  #endif
  #ifdef CONFIG_SPL_ONENAND_SUPPORT
        case BOOT_DEVICE_ONENAND:
        case BOOT_DEVICE_USBETH:
                spl_net_load_image("usb_ether");
                break;
 +#endif
 +#ifdef CONFIG_SPL_USB_SUPPORT
 +      case BOOT_DEVICE_USB:
 +              spl_usb_load_image();
 +              break;
 +#endif
 +#ifdef CONFIG_SPL_SATA_SUPPORT
 +      case BOOT_DEVICE_SATA:
 +              spl_sata_load_image();
 +              break;
  #endif
        default:
 -              printf("SPL: Unsupported Boot Device\n");
 +#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 +              printf("SPL: Unsupported Boot Device %d\n", boot_device);
 +#endif
                hang();
        }
  
        default:
                debug("Unsupported OS image.. Jumping nevertheless..\n");
        }
 +#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE)
 +      debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
 +            gd->malloc_ptr / 1024);
 +#endif
 +
        jump_to_image_no_args(&spl_image);
  }
  
diff --combined common/spl/spl_nand.c
index b7801cb4605f16c54c99f65e3e8ed93db5d3e564,da14d1faaf97bb2b0f06c412d0017a2ef52217d9..f58c21a7d646a440add27647608fa0be6df123ae
  #include <asm/io.h>
  #include <nand.h>
  
- void spl_nand_load_image(void)
 +#if defined(CONFIG_SPL_NAND_RAW_ONLY)
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
++int spl_nand_load_image(void)
 +{
++      int ret;
++
 +      nand_init();
 +
-       spl_set_header_raw_uboot();
++      ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 +                          CONFIG_SYS_NAND_U_BOOT_SIZE,
 +                          (void *)CONFIG_SYS_NAND_U_BOOT_DST);
- void spl_nand_load_image(void)
 +      nand_deselect();
++      if (ret)
++              return ret;
++
++      spl_set_header_raw_uboot();
++      return 0;
 +}
 +#else
+ int spl_nand_load_image(void)
  {
+       int ret;
        struct image_header *header;
        int *src __attribute__((unused));
        int *dst __attribute__((unused));
@@@ -32,7 -21,7 +39,7 @@@
        nand_init();
  
        /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
-       header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+       header = (struct image_header *)CONFIG_SYS_TEXT_BASE;
  #ifdef CONFIG_SPL_OS_BOOT
        if (!spl_start_uboot()) {
                /*
  
                /* load linux */
                nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
 -                      CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
 +                      sizeof(*header), (void *)header);
                spl_parse_image_header(header);
                if (header->ih_os == IH_OS_LINUX) {
                        /* happy - was a linux */
                        nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
                                spl_image.size, (void *)spl_image.load_addr);
                        nand_deselect();
-                       return;
+                       return 0;
                } else {
-                       puts("The Expected Linux image was not "
-                               "found. Please check your NAND "
+                       printf("The Expected Linux image was not"
+                               "found. Please check your NAND"
                                "configuration.\n");
-                       puts("Trying to start u-boot now...\n");
+                       printf("Trying to start u-boot now...\n");
                }
        }
  #endif
  #ifdef CONFIG_NAND_ENV_DST
        nand_spl_load_image(CONFIG_ENV_OFFSET,
 -              CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
 +              sizeof(*header), (void *)header);
        spl_parse_image_header(header);
        nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
                (void *)spl_image.load_addr);
  #ifdef CONFIG_ENV_OFFSET_REDUND
        nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
 -              CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
 +              sizeof(*header), (void *)header);
        spl_parse_image_header(header);
        nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
                (void *)spl_image.load_addr);
  #endif
  #endif
        /* Load u-boot */
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-               sizeof(*header), (void *)header);
-       spl_parse_image_header(header);
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-               spl_image.size, (void *)spl_image.load_addr);
+       ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                               CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+       if (ret == 0) {
+               spl_parse_image_header(header);
+               ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                                       spl_image.size, (void *)spl_image.load_addr);
+       }
        nand_deselect();
+       return ret;
  }
 +#endif
diff --combined common/xyzModem.c
index 56f4bcaf99453d04bac277b39a63688ed6836263,82039df1f3de6e7b727356f7033e3f5f884f965e..8e35e99a0df76ded98f8537f3d62d497b0df4c4b
@@@ -37,7 -37,7 +37,7 @@@
  #define BSP 0x08
  #define NAK 0x15
  #define CAN 0x18
- #define EOF 0x1A              /* ^Z for DOS officionados */
+ #define EOF 0x1A              /* ^Z for DOS aficionados */
  
  #define USE_YMODEM_LENGTH
  
@@@ -203,7 -203,7 +203,7 @@@ parse_num (char *s, unsigned long *val
  static int
  zm_dprintf (char *fmt, ...)
  {
-   int cur_console;
+   int cur_console __attribute__((unused));
    va_list args;
  
    va_start (args, fmt);
  #ifdef REDBOOT
    CYGACC_CALL_IF_SET_CONSOLE_COMM (cur_console);
  #endif
+   return 0;
  }
  
- static void
+ static inline void
  zm_flush (void)
  {
  }
@@@ -250,7 -251,7 +251,7 @@@ zm_dprintf (char *fmt, ...
    return len;
  }
  
- static void
+ static inline void
  zm_flush (void)
  {
  #ifdef REDBOOT
@@@ -275,19 -276,19 +276,19 @@@ zm_dump_buf (void *buf, int len
  static unsigned char zm_buf[2048];
  static unsigned char *zm_bp;
  
- static void
+ static inline void
  zm_new (void)
  {
    zm_bp = zm_buf;
  }
  
- static void
+ static inline void
  zm_save (unsigned char c)
  {
    *zm_bp++ = c;
  }
  
- static void
+ static inline void
  zm_dump (int line)
  {
    zm_dprintf ("Packet at line: %d\n", line);
@@@ -759,8 -760,7 +760,8 @@@ xyzModem_stream_terminate (bool abort, 
         * If we don't eat it now, RedBoot will think the user typed it.
         */
        ZM_DEBUG (zm_dprintf ("Trailing gunk:\n"));
 -      while ((c = (*getc) ()) > -1);
 +      while ((c = (*getc) ()) > -1)
 +        ;
        ZM_DEBUG (zm_dprintf ("\n"));
        /*
         * Make a small delay to give terminal programs like minicom
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b6d39bfd38dfbacb21e2137d6480ed0ca91740c9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cf591701c4c0d3c962e4d1d2cc46254795b81f46
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,ENV_IS_NOWHERE
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8a90e59fbb4278b7405f51c5e6fb4ad9cc234eb2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_256M
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..58ef67f2d101a47a90767fe0eb60e8b27be870f0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_256M,ENV_IS_NOWHERE
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d2af8c647bd305c96fae53427cc35a03a1c4cff8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,SYS_NAND_BLOCKS=2048
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6c85a34c89692137c4583f33e510d2f7b538c21d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,SYS_NAND_BLOCKS=2048,ENV_IS_NOWHERE
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..83793926f65fd12ab3f930e702d9b059774f2b7b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28_S,SDRAM_SIZE=SZ_64M
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..67430cd14c306bde963df2d0b4a6653576672cc7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX28_S,SDRAM_SIZE=SZ_64M,ENV_IS_NOWHERE
++CONFIG_ARM=y
++CONFIG_TARGET_TX28=y
diff --combined configs/tx48_defconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..07dd3a627ca7b37e807f2c72a0b70a3f5e9b97c1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_MPU_CLK=720,SYS_DDR_CLK=400
++CONFIG_ARM=y
++CONFIG_TARGET_TX48=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4e6ddb01b94d5375b87b345f52a184ac6630a7de
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_CPU_CLK=800,NR_DRAM_BANKS=1
++CONFIG_ARM=y
++CONFIG_TARGET_TX51=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3dd883d009bc9274211bd3118364c76cf12e1be2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_CPU_CLK=800,NR_DRAM_BANKS=2
++CONFIG_ARM=y
++CONFIG_TARGET_TX51=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4cf3dd8eaea9f97288c0e446f86eb6d58d6d0d4b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=2,SYS_SDRAM_SIZE=SZ_2G
++CONFIG_ARM=y
++CONFIG_TARGET_TX53=y
++CONFIG_TARGET_TX53_1232=y
++CONFIG_TX53_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_ENV_IS_IN_NAND=y
++CONFIG_FEC_MXC_PHYADDR=0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c7e14868993ed1672f6d20054f6980d7caa8caab
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=1
++CONFIG_ARM=y
++CONFIG_TARGET_TX53=y
++CONFIG_TARGET_TX53_X030=y
++CONFIG_TX53_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_CMD_I2C=y
++CONFIG_ENV_IS_IN_NAND=y
++CONFIG_FEC_MXC_PHYADDR=0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e4b77765eedd62e549d974ee81e13d83db9620d2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=1,SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_TARGET_TX53=y
++CONFIG_TARGET_TX53_X130=y
++CONFIG_TX53_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_ENV_IS_IN_NAND=y
++CONFIG_FEC_MXC_PHYADDR=0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8fd9adab4bbf58b7fab92c11ba6168a7d1618f42
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=2,SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_TARGET_TX53=y
++CONFIG_TARGET_TX53_X131=y
++CONFIG_TX53_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_ENV_IS_IN_NAND=y
++CONFIG_FEC_MXC_PHYADDR=0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3b441cfea93931b9304ebe32b614ebc3b95bf995
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_1020=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..228be88ea59f7de59050f714d76e3e442c687ce7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_1020=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..524cb99e8fce052531dd438d139f85986b5300a9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_1020=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f5c3bf55f6212a615409df9f87c66c85ab2110a8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_10X0=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9b07e4951086ace318d5cf9e31269e31f3ca836a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_10X0=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c0533765e40698d9f25f865e98c38233c2a92eed
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_10X0=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..975bdf65f5aa2ec3084f8759f5580bca75c1042d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_11X0=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e3a2132f0b3648f91078371047ab794b6c27adc9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_11X0=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4362900034922d296d353bc9e06c55dc81fe19cc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6Q=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6Q_11X0=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b59b96bbf5dab5cdf69a73dee5921e4ff66dd29d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8034=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..74e3feb01cbef740f657f4a9c77b7a14cfce7ad7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8034=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d3cdd4dc0c4f7aa74182627c7f32ff717c9f056f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8034=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6a06f03d8d607cb6477f5b0760a25f384a910a44
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8035=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5706c997c0124eb8dad38b15750224e913f73fae
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8035=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a00b5dd26aa40e5aeb99a40868c7d56b835d7d0c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6S=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6S_8035=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eab8f56ea6fe8f15b489791e11e64c3229243732
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8011=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d72a09b2351c0f816c69a22c42212558202e1ae1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8011=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..677ad9945f00a2ded62361d7f0ef0f23070afe0a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8011=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ae834e6ed30220585f19b76ffafda6bea208abef
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,23 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8012=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ec5692b30d2fbba5e04505792de80d3f7598dabd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,23 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8012=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a5753b19f94c569ea47a23d97fed334b6950cea8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,23 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8012=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9a11a46d3716f01ef1bc596e3750b45cd63d92c0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8033=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3f0f9777f53892177561c4183f1a4b2a91e60eeb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8033=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dfb49be7001b1ffed302bc00355ac0c8e69684fb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_8033=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fb33c2aef2c6d5c4adeb7de633d36d610e699e00
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_80X0=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e72b3fb86f17b523112316508b9cddca923a9f1a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_80X0=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2cc8c6bbb4e61553bd18e052101dd2ee5d428f3b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_80X0=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cbe9d894f862ccf12855905e33dbc63bcb572c2c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f956d1f12082f9352c348607067e784264c0c65c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..29c56741c43c83a68300d912369491aab203b3bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f303f4a36f542e8feabf6984771ed1a0e9d624a7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1bc01d5b9481babbbec6e51aa70663e84a749075
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT_MFG=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4a457e152a7c5f627d10f3b46a7376d57cfc1333
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++CONFIG_ARM=y
++CONFIG_MX6DL=y
++CONFIG_TARGET_TX6=y
++CONFIG_TARGET_TX6U_81X0=y
++CONFIG_TX6_UBOOT_NOENV=y
++CONFIG_CMD_MII=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_PING=y
++CONFIG_BOOTP_SUBNETMASK=y
++CONFIG_BOOTP_GATEWAY=y
++CONFIG_BOOTP_DNS=y
++CONFIG_MMC=y
++CONFIG_FSL_ESDHC=y
++CONFIG_FSL_USDHC=y
++CONFIG_LCD=y
++CONFIG_NET=y
++CONFIG_NETDEVICES=y
++CONFIG_FEC_MXC=y
++CONFIG_IMX_WATCHDOG=y
++CONFIG_CMD_I2C=y
++CONFIG_NAND=y
++CONFIG_NAND_MXS=y
diff --combined disk/part.c
index 43485c9148b0f404e91cb0f45f9a3c76b2267578,6827744df363517738570ee0d10dd79f6ef13781..18fcc7b15633fdb3813152875e6f1b3ba4eb602c
  struct block_drvr {
        char *name;
        block_dev_desc_t* (*get_dev)(int dev);
 +      int (*select_hwpart)(int dev_num, int hwpart);
  };
  
  static const struct block_drvr block_drvr[] = {
  #if defined(CONFIG_CMD_IDE)
        { .name = "ide", .get_dev = ide_get_dev, },
  #endif
+ #if defined(CONFIG_CMD_PATA)
+       { .name = "pata", .get_dev = pata_get_dev, },
+ #endif
  #if defined(CONFIG_CMD_SATA)
        {.name = "sata", .get_dev = sata_get_dev, },
  #endif
        { .name = "usb", .get_dev = usb_stor_get_dev, },
  #endif
  #if defined(CONFIG_MMC)
 -      { .name = "mmc", .get_dev = mmc_get_dev, },
 +      {
 +              .name = "mmc",
 +              .get_dev = mmc_get_dev,
 +              .select_hwpart = mmc_select_hwpart,
 +      },
  #endif
  #if defined(CONFIG_SYSTEMACE)
        { .name = "ace", .get_dev = systemace_get_dev, },
 +#endif
 +#if defined(CONFIG_SANDBOX)
 +      { .name = "host", .get_dev = host_get_dev, },
  #endif
        { },
  };
  DECLARE_GLOBAL_DATA_PTR;
  
  #ifdef HAVE_BLOCK_DEVICE
 -block_dev_desc_t *get_dev(const char *ifname, int dev)
 +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);
 +      int (*select_hwpart)(int dev_num, int hwpart);
        char *name;
 +      int ret;
  
        if (!ifname)
                return NULL;
        while (drvr->name) {
                name = drvr->name;
                reloc_get_dev = drvr->get_dev;
 +              select_hwpart = drvr->select_hwpart;
  #ifdef CONFIG_NEEDS_MANUAL_RELOC
                name += gd->reloc_off;
                reloc_get_dev += gd->reloc_off;
 +              if (select_hwpart)
 +                      select_hwpart += gd->reloc_off;
  #endif
 -              if (strncmp(ifname, name, strlen(name)) == 0)
 -                      return reloc_get_dev(dev);
 +              if (strncmp(ifname, name, strlen(name)) == 0) {
 +                      block_dev_desc_t *dev_desc = reloc_get_dev(dev);
 +                      if (!dev_desc)
 +                              return NULL;
 +                      if (hwpart == 0 && !select_hwpart)
 +                              return dev_desc;
 +                      if (!select_hwpart)
 +                              return NULL;
 +                      ret = select_hwpart(dev_desc->dev, hwpart);
 +                      if (ret < 0)
 +                              return NULL;
 +                      return dev_desc;
 +              }
                drvr++;
        }
        return NULL;
  }
 +
 +block_dev_desc_t *get_dev(const char *ifname, int dev)
 +{
 +      return get_dev_hwpart(ifname, dev, 0);
 +}
  #else
 +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
 +{
 +      return NULL;
 +}
 +
  block_dev_desc_t *get_dev(const char *ifname, int dev)
  {
        return NULL;
@@@ -133,7 -102,7 +136,7 @@@ typedef lbaint_t lba512_t
   * Overflowless variant of (block_count * mul_by / div_by)
   * when div_by > mul_by
   */
 -static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by)
 +static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, lba512_t div_by)
  {
        lba512_t bc_quot, bc_rem;
  
@@@ -215,8 -184,7 +218,8 @@@ void dev_print (block_dev_desc_t *dev_d
  
                lba512 = (lba * (dev_desc->blksz/512));
                /* round to 1 digit */
 -              mb = lba512_muldiv(lba512, 10, 2048);   /* 2048 = (1024 * 1024) / 512 MB */
 +              /* 2048 = (1024 * 1024) / 512 MB */
 +              mb = lba512_muldiv(lba512, 10, 2048);
  
                mb_quot = mb / 10;
                mb_rem  = mb - (10 * mb_quot);
  
  #ifdef HAVE_BLOCK_DEVICE
  
 -void init_part (block_dev_desc_t * dev_desc)
 +void init_part(block_dev_desc_t *dev_desc)
  {
  #ifdef CONFIG_ISO_PARTITION
        if (test_part_iso(dev_desc) == 0) {
        defined(CONFIG_AMIGA_PARTITION) || \
        defined(CONFIG_EFI_PARTITION)
  
 -static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
 +static void print_part_header(const char *type, block_dev_desc_t *dev_desc)
  {
        puts ("\nPartition Map for ");
        switch (dev_desc->if_type) {
        case IF_TYPE_MMC:
                puts ("MMC");
                break;
 +      case IF_TYPE_HOST:
 +              puts("HOST");
 +              break;
        default:
                puts ("UNKNOWN");
                break;
  
  #endif /* any CONFIG_..._PARTITION */
  
 -void print_part (block_dev_desc_t * dev_desc)
 +void print_part(block_dev_desc_t * dev_desc)
  {
  
                switch (dev_desc->part_type) {
  
  #endif /* HAVE_BLOCK_DEVICE */
  
 -int get_partition_info(block_dev_desc_t *dev_desc, int part
 -                                      , disk_partition_t *info)
 +int get_partition_info(block_dev_desc_t *dev_desc, int part,
 +                     disk_partition_t *info)
  {
  #ifdef HAVE_BLOCK_DEVICE
  
        return -1;
  }
  
 -int get_device(const char *ifname, const char *dev_str,
 +int get_device(const char *ifname, const char *dev_hwpart_str,
               block_dev_desc_t **dev_desc)
  {
        char *ep;
 -      int dev;
 +      char *dup_str = NULL;
 +      const char *dev_str, *hwpart_str;
 +      int dev, hwpart;
 +
 +      hwpart_str = strchr(dev_hwpart_str, '.');
 +      if (hwpart_str) {
 +              dup_str = strdup(dev_hwpart_str);
 +              dup_str[hwpart_str - dev_hwpart_str] = 0;
 +              dev_str = dup_str;
 +              hwpart_str++;
 +      } else {
 +              dev_str = dev_hwpart_str;
 +              hwpart = 0;
 +      }
  
        dev = simple_strtoul(dev_str, &ep, 16);
        if (*ep) {
                printf("** Bad device specification %s %s **\n",
                       ifname, dev_str);
 -              return -1;
 +              dev = -1;
 +              goto cleanup;
 +      }
 +
 +      if (hwpart_str) {
 +              hwpart = simple_strtoul(hwpart_str, &ep, 16);
 +              if (*ep) {
 +                      printf("** Bad HW partition specification %s %s **\n",
 +                          ifname, hwpart_str);
 +                      dev = -1;
 +                      goto cleanup;
 +              }
        }
  
 -      *dev_desc = get_dev(ifname, dev);
 +      *dev_desc = get_dev_hwpart(ifname, dev, hwpart);
        if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
 -              printf("** Bad device %s %s **\n", ifname, dev_str);
 -              return -1;
 +              printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
 +              dev = -1;
 +              goto cleanup;
        }
  
 +cleanup:
 +      free(dup_str);
        return dev;
  }
  
@@@ -512,14 -450,12 +515,14 @@@ int get_device_and_partition(const cha
        disk_partition_t tmpinfo;
  
        /*
 -       * For now, we have a special case for sandbox, since there is no
 -       * real block device support.
 +       * Special-case a pseudo block device "hostfs", to allow access to the
 +       * host's own filesystem.
         */
 -      if (0 == strcmp(ifname, "host")) {
 +      if (0 == strcmp(ifname, "hostfs")) {
                *dev_desc = NULL;
 -              info->start = info->size =  info->blksz = 0;
 +              info->start = 0;
 +              info->size = 0;
 +              info->blksz = 0;
                info->bootable = 0;
                strcpy((char *)info->type, BOOT_PART_TYPE);
                strcpy((char *)info->name, "Sandbox host");
diff --combined drivers/dma/Kconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,0000000000000000000000000000000000000000..25cc5f80c8723a42be1480a6bdaf39ddfc2711d6
mode 100644,000000..100644
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++config APBH_DMA
++      bool "Freescale MXS and i.MX6 APBH DMA support"
++      default y
++      depends on MX28 || MX6
++
++config APBH_DMA_BURST
++      bool "Enable DMA burst mode"
++      default y
++      depends on APBH_DMA
++
++config APBH_DMA_BURST8
++      bool "Use 8-beat DMA bursts"
++      default y
++      depends on APBH_DMA_BURST
diff --combined drivers/dma/apbh_dma.c
index 22defcd7d9223be898b18cdc8ae1236a38272671,eab87bc9f4d6fe381684510787386a9e81c6ead8..983111ad29e8a18b360322ba09b908cc4785eb8a
@@@ -23,6 -23,7 +23,7 @@@
  #include <asm/imx-common/regs-apbh.h>
  
  static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS];
+ static struct mxs_apbh_regs *apbh_regs = (struct mxs_apbh_regs *)MXS_APBH_BASE;
  
  /*
   * Test is the DMA channel is valid channel
@@@ -31,12 -32,16 +32,16 @@@ int mxs_dma_validate_chan(int channel
  {
        struct mxs_dma_chan *pchan;
  
-       if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
+       if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) {
+               printf("Invalid DMA channel %d\n", channel);
                return -EINVAL;
+       }
  
        pchan = mxs_dma_channels + channel;
-       if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED))
+       if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED)) {
+               printf("DMA channel %d not allocated\n", channel);
                return -EINVAL;
+       }
  
        return 0;
  }
@@@ -65,8 -70,6 +70,6 @@@ static unsigned int mxs_dma_cmd_address
   */
  static int mxs_dma_read_semaphore(int channel)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        uint32_t tmp;
        int ret;
  
@@@ -83,7 -86,7 +86,7 @@@
  }
  
  #ifndef       CONFIG_SYS_DCACHE_OFF
- void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
static void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
  {
        uint32_t addr;
        uint32_t size;
@@@ -94,7 -97,9 +97,9 @@@
        flush_dcache_range(addr, addr + size);
  }
  #else
- inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {}
+ static inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+ {
+ }
  #endif
  
  /*
   */
  static int mxs_dma_enable(int channel)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        unsigned int sem;
        struct mxs_dma_chan *pchan;
        struct mxs_dma_desc *pdesc;
  
        pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node);
        if (pdesc == NULL)
-               return -EFAULT;
+               return -EINVAL;
  
        if (pchan->flags & MXS_DMA_FLAGS_BUSY) {
                if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN))
        } else {
                pchan->active_num += pchan->pending_num;
                pchan->pending_num = 0;
+               writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
+                       &apbh_regs->hw_apbh_ctrl0_clr);
                writel(mxs_dma_cmd_address(pdesc),
                        &apbh_regs->ch[channel].hw_apbh_ch_nxtcmdar);
                writel(pchan->active_num,
                        &apbh_regs->ch[channel].hw_apbh_ch_sema);
-               writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
-                       &apbh_regs->hw_apbh_ctrl0_clr);
        }
  
        pchan->flags |= MXS_DMA_FLAGS_BUSY;
  static int mxs_dma_disable(int channel)
  {
        struct mxs_dma_chan *pchan;
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
  
        ret = mxs_dma_validate_chan(channel);
  
        pchan = mxs_dma_channels + channel;
  
-       if (!(pchan->flags & MXS_DMA_FLAGS_BUSY))
+       if ((pchan->flags & MXS_DMA_FLAGS_BUSY)) {
+               printf("%s: DMA channel %d busy\n", __func__, channel);
                return -EINVAL;
+       }
        writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
                &apbh_regs->hw_apbh_ctrl0_set);
-       pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
        pchan->active_num = 0;
        pchan->pending_num = 0;
        list_splice_init(&pchan->active, &pchan->done);
   */
  static int mxs_dma_reset(int channel)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
  #if defined(CONFIG_MX23)
-       uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set);
+       uint32_t *setreg = &apbh_regs->hw_apbh_ctrl0_set;
        uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET;
  #elif (defined(CONFIG_MX28) || defined(CONFIG_MX6))
-       uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set);
+       uint32_t *setreg = &apbh_regs->hw_apbh_channel_ctrl_set;
        uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
  #endif
  
   */
  static int mxs_dma_enable_irq(int channel, int enable)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
  
        ret = mxs_dma_validate_chan(channel);
   */
  static int mxs_dma_ack_irq(int channel)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
  
        ret = mxs_dma_validate_chan(channel);
@@@ -296,6 -290,7 +290,7 @@@ static int mxs_dma_request(int channel
        pchan->flags |= MXS_DMA_FLAGS_ALLOCATED;
        pchan->active_num = 0;
        pchan->pending_num = 0;
+       pchan->timeout = 10000000;
  
        INIT_LIST_HEAD(&pchan->active);
        INIT_LIST_HEAD(&pchan->done);
@@@ -333,6 -328,44 +328,44 @@@ int mxs_dma_release(int channel
        return 0;
  }
  
+ /*
+  * Set the timeout for any DMA operation started with mxs_dma_go()
+  * The timeout value given is in milliseconds
+  */
+ int mxs_dma_set_timeout(int channel, unsigned long timeout)
+ {
+       int ret;
+       struct mxs_dma_chan *pchan;
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return ret;
+       pchan = &mxs_dma_channels[channel];
+       if (pchan->flags & MXS_DMA_FLAGS_BUSY)
+               return -EBUSY;
+       if (timeout > ~0UL / 1000)
+               return -EINVAL;
+       pchan->timeout = timeout;
+       return 0;
+ }
+ unsigned long mxs_dma_get_timeout(int channel)
+ {
+       int ret;
+       struct mxs_dma_chan *pchan;
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return 0;
+       pchan = &mxs_dma_channels[channel];
+       return pchan->timeout;
+ }
  /*
   * Allocate DMA descriptor
   */
@@@ -499,8 -532,6 +532,6 @@@ static int mxs_dma_finish(int channel, 
   */
  static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
  
        ret = mxs_dma_validate_chan(chan);
   */
  int mxs_dma_go(int chan)
  {
-       uint32_t timeout = 10000000;
        int ret;
+       struct mxs_dma_chan *pchan;
        LIST_HEAD(tmp_desc_list);
  
+       ret = mxs_dma_validate_chan(chan);
+       if (ret)
+               return ret;
+       pchan = &mxs_dma_channels[chan];
        mxs_dma_enable_irq(chan, 1);
-       mxs_dma_enable(chan);
+       ret = mxs_dma_enable(chan);
+       if (ret) {
+               mxs_dma_enable_irq(chan, 0);
+               return ret;
+       }
  
        /* Wait for DMA to finish. */
-       ret = mxs_dma_wait_complete(timeout, chan);
+       ret = mxs_dma_wait_complete(pchan->timeout * 1000, chan);
  
        /* Clear out the descriptors we just ran. */
        mxs_dma_finish(chan, &tmp_desc_list);
        return ret;
  }
  
 +/*
 + * Execute a continuously running circular DMA descriptor.
 + * NOTE: This is not intended for general use, but rather
 + *     for the LCD driver in Smart-LCD mode. It allows
 + *     continuous triggering of the RUN bit there.
 + */
 +void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc)
 +{
 +      struct mxs_apbh_regs *apbh_regs =
 +              (struct mxs_apbh_regs *)MXS_APBH_BASE;
 +
 +      mxs_dma_flush_desc(pdesc);
 +
 +      mxs_dma_enable_irq(chan, 1);
 +
 +      writel(mxs_dma_cmd_address(pdesc),
 +              &apbh_regs->ch[chan].hw_apbh_ch_nxtcmdar);
 +      writel(1, &apbh_regs->ch[chan].hw_apbh_ch_sema);
 +      writel(1 << (chan + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
 +              &apbh_regs->hw_apbh_ctrl0_clr);
 +}
 +
  /*
   * Initialize the DMA hardware
   */
  void mxs_dma_init(void)
  {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        mxs_reset_block(&apbh_regs->hw_apbh_ctrl0_reg);
  
  #ifdef CONFIG_APBH_DMA_BURST8
diff --combined drivers/gpio/Makefile
index aa11f15423a4a7968462fc7569d7edbf8c72eeee,be64df225362c525dc0869505e0037f76107a48b..e035a7433366dda97a9249bce6d7d291369304e3
@@@ -5,35 -5,53 +5,36 @@@
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
 -include $(TOPDIR)/config.mk
 -
 -LIB   := $(obj)libgpio.o
 -
 -COBJS-y                               += gpiolib.o
 -
 -COBJS-$(CONFIG_AM33XX_GPIO)   += am33xx_gpio.o
 -COBJS-$(CONFIG_AT91_GPIO)     += at91_gpio.o
 -COBJS-$(CONFIG_INTEL_ICH6_GPIO)       += intel_ich6_gpio.o
 -COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
 -COBJS-$(CONFIG_MARVELL_GPIO)  += mvgpio.o
 -COBJS-$(CONFIG_MARVELL_MFP)   += mvmfp.o
 -COBJS-$(CONFIG_MXC_GPIO)      += mxc_gpio.o
 -COBJS-$(CONFIG_MXS_GPIO)      += mxs_gpio.o
 -COBJS-$(CONFIG_PCA953X)               += pca953x.o
 -COBJS-$(CONFIG_PCA9698)               += pca9698.o
 -COBJS-$(CONFIG_S5P)           += s5p_gpio.o
 -COBJS-$(CONFIG_SANDBOX_GPIO)  += sandbox.o
 -COBJS-$(CONFIG_SPEAR_GPIO)    += spear_gpio.o
 -COBJS-$(CONFIG_TEGRA_GPIO)    += tegra_gpio.o
 -COBJS-$(CONFIG_DA8XX_GPIO)    += da8xx_gpio.o
 -COBJS-$(CONFIG_DM644X_GPIO)   += da8xx_gpio.o
 -COBJS-$(CONFIG_ALTERA_PIO)    += altera_pio.o
 -COBJS-$(CONFIG_MPC83XX_GPIO)  += mpc83xx_gpio.o
 -COBJS-$(CONFIG_SH_GPIO_PFC)   += sh_pfc.o
 -COBJS-$(CONFIG_OMAP_GPIO)     += omap_gpio.o
 -COBJS-$(CONFIG_DB8500_GPIO)   += db8500_gpio.o
 -COBJS-$(CONFIG_BCM2835_GPIO)  += bcm2835_gpio.o
 -COBJS-$(CONFIG_S3C2440_GPIO)  += s3c2440_gpio.o
 -COBJS-$(CONFIG_XILINX_GPIO)   += xilinx_gpio.o
 -COBJS-$(CONFIG_ADI_GPIO2)     += adi_gpio2.o
 -
 -COBJS := $(COBJS-y)
 -SRCS  := $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -
 -all:  $(LIB)
 -
 -$(LIB):       $(obj).depend $(OBJS)
 -      $(call cmd_link_o_target, $(OBJS))
 -
 -
 -#########################################################################
 -
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -########################################################################
 +ifndef CONFIG_SPL_BUILD
 +obj-$(CONFIG_DM_GPIO)         += gpio-uclass.o
 +endif
 +
- obj-$(CONFIG_AT91_GPIO)       += at91_gpio.o
++obj-$(CONFIG_AM33XX_GPIO)     += am33xx_gpio.o
++obj-$(CONFIG_AT91_GPIO)               += at91_gpio.o
 +obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
 +obj-$(CONFIG_KIRKWOOD_GPIO)   += kw_gpio.o
- obj-$(CONFIG_KONA_GPIO)       += kona_gpio.o
++obj-$(CONFIG_KONA_GPIO)               += kona_gpio.o
 +obj-$(CONFIG_MARVELL_GPIO)    += mvgpio.o
 +obj-$(CONFIG_MARVELL_MFP)     += mvmfp.o
- obj-$(CONFIG_MXC_GPIO)        += mxc_gpio.o
- obj-$(CONFIG_MXS_GPIO)        += mxs_gpio.o
++obj-$(CONFIG_MXC_GPIO)                += mxc_gpio.o
++obj-$(CONFIG_MXS_GPIO)                += mxs_gpio.o
 +obj-$(CONFIG_PCA953X)         += pca953x.o
 +obj-$(CONFIG_PCA9698)         += pca9698.o
 +obj-$(CONFIG_S5P)             += s5p_gpio.o
 +obj-$(CONFIG_SANDBOX_GPIO)    += sandbox.o
 +obj-$(CONFIG_SPEAR_GPIO)      += spear_gpio.o
 +obj-$(CONFIG_TEGRA_GPIO)      += tegra_gpio.o
 +obj-$(CONFIG_DA8XX_GPIO)      += da8xx_gpio.o
 +obj-$(CONFIG_DM644X_GPIO)     += da8xx_gpio.o
 +obj-$(CONFIG_ALTERA_PIO)      += altera_pio.o
 +obj-$(CONFIG_MPC83XX_GPIO)    += mpc83xx_gpio.o
 +obj-$(CONFIG_SH_GPIO_PFC)     += sh_pfc.o
- obj-$(CONFIG_OMAP_GPIO)       += omap_gpio.o
++obj-$(CONFIG_OMAP_GPIO)               += omap_gpio.o
 +obj-$(CONFIG_DB8500_GPIO)     += db8500_gpio.o
 +obj-$(CONFIG_BCM2835_GPIO)    += bcm2835_gpio.o
 +obj-$(CONFIG_S3C2440_GPIO)    += s3c2440_gpio.o
 +obj-$(CONFIG_XILINX_GPIO)     += xilinx_gpio.o
- obj-$(CONFIG_ADI_GPIO2)       += adi_gpio2.o
++obj-$(CONFIG_ADI_GPIO2)               += adi_gpio2.o
 +obj-$(CONFIG_TCA642X)         += tca642x.o
 +oby-$(CONFIG_SX151X)          += sx151x.o
 +obj-$(CONFIG_SUNXI_GPIO)      += sunxi_gpio.o
index 0000000000000000000000000000000000000000,de0bc475ca8cbc65f36ebed21f3f4e9719d4a0d6..4893d25440b896ce45139185cf1d911c84c4fdc2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,130 +1,130 @@@
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * See file CREDITS for list of people who contributed to this
+  * project.
+  *
+  * 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.
+  *
+  */
+ #include <common.h>
+ #include <errno.h>
+ #include <asm/io.h>
+ #include <asm/bitops.h>
++#include <linux/sizes.h>
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/gpio.h>
+ struct gpio_regs {
+       unsigned int res1[0x134 / 4];
+       unsigned int oe;                /* 0x134 */
+       unsigned int datain;            /* 0x138 */
+       unsigned int res2[0x54 / 4];
+       unsigned int cleardataout;      /* 0x190 */
+       unsigned int setdataout;        /* 0x194 */
+ };
+ static const struct gpio_regs *gpio_base[] = {
+       (struct gpio_regs *)AM33XX_GPIO0_BASE,
+       (struct gpio_regs *)AM33XX_GPIO1_BASE,
+       (struct gpio_regs *)AM33XX_GPIO2_BASE,
+       (struct gpio_regs *)AM33XX_GPIO3_BASE,
+ };
+ static unsigned long gpio_map[ARRAY_SIZE(gpio_base)] __attribute__((section("data")));
+ #define MAX_GPIO      (ARRAY_SIZE(gpio_base) * 32)
+ int gpio_request(unsigned gpio, const char *name)
+ {
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (test_and_set_bit(gpio, gpio_map))
+               return -EBUSY;
+       return 0;
+ }
+ int gpio_free(unsigned gpio)
+ {
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (test_bit(gpio, gpio_map))
+               __clear_bit(gpio, gpio_map);
+       else
+               printf("ERROR: trying to free unclaimed GPIO %u\n", gpio);
+       return 0;
+ }
+ int gpio_set_value(unsigned gpio, int val)
+ {
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (val)
+               writel(mask, &gpio_base[bank]->setdataout);
+       else
+               writel(mask, &gpio_base[bank]->cleardataout);
+       return 0;
+ }
+ int gpio_get_value(unsigned gpio)
+ {
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       return (readl(&gpio_base[bank]->datain) & mask) != 0;
+ }
+ int gpio_direction_input(unsigned gpio)
+ {
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       writel(readl(&gpio_base[bank]->oe) | mask, &gpio_base[bank]->oe);
+       return 0;
+ }
+ int gpio_direction_output(unsigned gpio, int val)
+ {
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       gpio_set_value(gpio, val);
+       writel(readl(&gpio_base[bank]->oe) & ~mask, &gpio_base[bank]->oe);
+       return 0;
+ }
index 255700ab18d2d93cf107fcbf3b5a10b2e66e855f,0000000000000000000000000000000000000000..7d8c361599638c9af6baf590cbf94182a44d1e9a
mode 100644,000000..100644
--- /dev/null
@@@ -1,469 -1,0 +1,522 @@@
 +/*
 + * Copyright (c) 2013 Google, Inc
 + *
 + * SPDX-License-Identifier:   GPL-2.0+
 + */
 +
 +#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
 + * gpio:      The numeric representation of the GPIO
 + *
 + * Convert the GPIO number to an entry in the list of GPIOs
 + * or GPIO blocks registered with the GPIO controller. Returns
 + * entry on success, NULL on error.
 + */
 +static int gpio_to_device(unsigned int gpio, struct udevice **devp,
 +                        unsigned int *offset)
 +{
 +      struct gpio_dev_priv *uc_priv;
 +      struct udevice *dev;
 +      int ret;
 +
 +      for (ret = uclass_first_device(UCLASS_GPIO, &dev);
 +           dev;
 +           ret = uclass_next_device(&dev)) {
 +              uc_priv = dev->uclass_priv;
 +              if (gpio >= uc_priv->gpio_base &&
 +                  gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
 +                      *devp = dev;
 +                      *offset = gpio - uc_priv->gpio_base;
 +                      return 0;
 +              }
 +      }
 +
 +      /* No such GPIO */
 +      return ret ? ret : -EINVAL;
 +}
 +
 +int gpio_lookup_name(const char *name, struct udevice **devp,
 +                   unsigned int *offsetp, unsigned int *gpiop)
 +{
 +      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)) {
 +              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))
 +                              break;
 +              }
 +      }
 +
 +      if (!dev)
 +              return ret ? ret : -EINVAL;
 +
 +      if (devp)
 +              *devp = dev;
 +      if (offsetp)
 +              *offsetp = offset;
 +      if (gpiop)
 +              *gpiop = uc_priv->gpio_base + offset;
 +
 +      return 0;
 +}
 +
 +/**
 + * gpio_request() - [COMPAT] Request GPIO
 + * 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;
 +
 +      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];
 +
 +      va_start(args, fmt);
 +      vscnprintf(buf, sizeof(buf), fmt, args);
 +      va_end(args);
 +      return gpio_request(gpio, buf);
 +}
 +
++int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
++              const char *label)
++{
++      int ret;
++
++      ret = gpio_request(gpio, label);
++      if (ret)
++              return ret;
++
++      if (flags == GPIOFLAG_INPUT)
++              gpio_direction_input(gpio);
++      else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
++              gpio_direction_output(gpio, 0);
++      else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
++              gpio_direction_output(gpio, 1);
++
++      return ret;
++}
++
++int gpio_request_array(const struct gpio *gpios, int count)
++{
++      int ret;
++      int i;
++
++      for (i = 0; i < count; i++) {
++              ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
++                              gpios[i].label);
++              if (ret) {
++                      printf("Failed to request GPIO%d (%u of %u): %d\n",
++                              gpios[i].gpio, i, count, ret);
++                      goto error;
++              }
++      }
++      return 0;
++
++error:
++      while (--i >= 0)
++              gpio_free(gpios[i].gpio);
++
++      return ret;
++}
++
 +/**
 + * gpio_free() - [COMPAT] Relinquish GPIO
 + * gpio:      GPIO number
 + *
 + * 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_free(unsigned gpio)
 +{
 +      struct gpio_dev_priv *uc_priv;
 +      unsigned int offset;
 +      struct udevice *dev;
 +      int ret;
 +
 +      ret = gpio_to_device(gpio, &dev, &offset);
 +      if (ret)
 +              return ret;
 +
 +      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;
 +}
 +
++int gpio_free_array(const struct gpio *gpios, int count)
++{
++      int ret = 0;
++      int i;
++
++      for (i = 0; i < count; i++)
++              ret |= gpio_free(gpios[i].gpio);
++
++      return ret;
++}
++
 +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;
 +}
 +
 +/**
 + * gpio_direction_input() - [COMPAT] Set GPIO direction to input
 + * gpio:      GPIO number
 + *
 + * 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_direction_input(unsigned gpio)
 +{
 +      unsigned int offset;
 +      struct udevice *dev;
 +      int ret;
 +
 +      ret = gpio_to_device(gpio, &dev, &offset);
 +      if (ret)
 +              return ret;
 +      ret = check_reserved(dev, offset, "dir_input");
 +
 +      return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
 +}
 +
 +/**
 + * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
 + * gpio:      GPIO number
 + * value:     Logical value to be set on the GPIO pin
 + *
 + * 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_direction_output(unsigned gpio, int value)
 +{
 +      unsigned int offset;
 +      struct udevice *dev;
 +      int ret;
 +
 +      ret = gpio_to_device(gpio, &dev, &offset);
 +      if (ret)
 +              return ret;
 +      ret = check_reserved(dev, offset, "dir_output");
 +
 +      return ret ? ret :
 +              gpio_get_ops(dev)->direction_output(dev, offset, value);
 +}
 +
 +/**
 + * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
 + * gpio:      GPIO number
 + *
 + * 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 the value of the GPIO pin, or negative value
 + * on error.
 + */
 +int gpio_get_value(unsigned gpio)
 +{
 +      unsigned int offset;
 +      struct udevice *dev;
 +      int ret;
 +
 +      ret = gpio_to_device(gpio, &dev, &offset);
 +      if (ret)
 +              return ret;
 +      ret = check_reserved(dev, offset, "get_value");
 +
 +      return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
 +}
 +
 +/**
 + * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
 + * gpio:      GPIO number
 + * value:     Logical value to be set on the GPIO pin.
 + *
 + * 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_set_value(unsigned gpio, int value)
 +{
 +      unsigned int offset;
 +      struct udevice *dev;
 +      int ret;
 +
 +      ret = gpio_to_device(gpio, &dev, &offset);
 +      if (ret)
 +              return ret;
 +      ret = check_reserved(dev, offset, "set_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)
 +{
 +      struct gpio_dev_priv *priv;
 +
 +      /* Must be called on an active device */
 +      priv = dev->uclass_priv;
 +      assert(priv);
 +
 +      *bit_count = priv->gpio_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;
 +}
 +
 +/*
 + * get a number comprised of multiple GPIO values. gpio_num_array points to
 + * the array of gpio pin numbers to scan, terminated by -1.
 + */
 +unsigned gpio_get_values_as_int(const int *gpio_num_array)
 +{
 +      int gpio;
 +      unsigned bitmask = 1;
 +      unsigned vector = 0;
 +
 +      while (bitmask &&
 +             ((gpio = *gpio_num_array++) != -1)) {
 +              if (gpio_get_value(gpio))
 +                      vector |= bitmask;
 +              bitmask <<= 1;
 +      }
 +      return vector;
 +}
 +
 +/* We need to renumber the GPIOs when any driver is probed/removed */
 +static int gpio_renumber(struct udevice *removed_dev)
 +{
 +      struct gpio_dev_priv *uc_priv;
 +      struct udevice *dev;
 +      struct uclass *uc;
 +      unsigned base;
 +      int ret;
 +
 +      ret = uclass_get(UCLASS_GPIO, &uc);
 +      if (ret)
 +              return ret;
 +
 +      /* Ensure that we have a base for each bank */
 +      base = 0;
 +      uclass_foreach_dev(dev, uc) {
 +              if (device_active(dev) && dev != removed_dev) {
 +                      uc_priv = dev->uclass_priv;
 +                      uc_priv->gpio_base = base;
 +                      base += uc_priv->gpio_count;
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +static int gpio_post_probe(struct udevice *dev)
 +{
 +      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)
 +{
 +      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) = {
 +      .id             = UCLASS_GPIO,
 +      .name           = "gpio",
 +      .post_probe     = gpio_post_probe,
 +      .pre_remove     = gpio_pre_remove,
 +      .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
 +};
diff --combined drivers/gpio/gpiolib.c
index 0000000000000000000000000000000000000000,ef314eefe94ac0e96a39fd3b378d50cbac998a25..63b287cda3aada77c86e304fbfe918b4ea56b428
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,55 +1,55 @@@
 -      if (flags == GPIOF_INPUT)
+ #include <common.h>
+ #include <asm-generic/gpio.h>
+ int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
+               const char *label)
+ {
+       int ret;
+       ret = gpio_request(gpio, label);
+       if (ret)
+               return ret;
 -      else if (flags == GPIOF_OUTPUT_INIT_LOW)
++      if (flags == GPIOFLAG_INPUT)
+               gpio_direction_input(gpio);
 -      else if (flags == GPIOF_OUTPUT_INIT_HIGH)
++      else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
+               gpio_direction_output(gpio, 0);
++      else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
+               gpio_direction_output(gpio, 1);
+       return ret;
+ }
+ int gpio_request_array(const struct gpio *gpios, int count)
+ {
+       int ret;
+       int i;
+       for (i = 0; i < count; i++) {
+               ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
+                               gpios[i].label);
+               if (ret) {
+                       printf("Failed to request GPIO%d (%u of %u): %d\n",
+                               gpios[i].gpio, i, count, ret);
+                       goto error;
+               }
+       }
+       return 0;
+ error:
+       while (--i >= 0)
+               gpio_free(gpios[i].gpio);
+       return ret;
+ }
+ int gpio_free_array(const struct gpio *gpios, int count)
+ {
+       int ret = 0;
+       int i;
+       for (i = 0; i < count; i++)
+               ret |= gpio_free(gpios[i].gpio);
+       return ret;
+ }
diff --combined drivers/gpio/mxc_gpio.c
index 8bb9e39b7231e522f87eaf9612ad5abf383931e7,65dc50df39442e83b24b6690458e3499acdf8ec5..a46d33e8d91b49e5861681b7546082d8a27648ed
@@@ -8,30 -8,17 +8,30 @@@
   * 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_TO_PORT(n)               (n / 32)
 +#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 */
  static unsigned long gpio_ports[] = {
@@@ -58,8 -45,10 +58,10 @@@ static int mxc_gpio_direction(unsigned 
        struct gpio_regs *regs;
        u32 l;
  
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
  
        gpio &= 0x1f;
  
@@@ -85,8 -74,10 +87,10 @@@ int gpio_set_value(unsigned gpio, int v
        struct gpio_regs *regs;
        u32 l;
  
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
  
        gpio &= 0x1f;
  
@@@ -108,28 -99,42 +112,42 @@@ int gpio_get_value(unsigned gpio
        struct gpio_regs *regs;
        u32 val;
  
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
  
        gpio &= 0x1f;
  
        regs = (struct gpio_regs *)gpio_ports[port];
  
-       val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
+       if (readl(&regs->gpio_dir) & (1 << gpio)) {
+               printf("WARNING: Reading status of output GPIO_%d_%d\n",
+                       port - GPIO_TO_PORT(0), gpio);
+               val = (readl(&regs->gpio_dr) >> gpio) & 0x01;
+       } else {
+               val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
+       }
        return val;
  }
  
  int gpio_request(unsigned gpio, const char *label)
  {
        unsigned int port = GPIO_TO_PORT(gpio);
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
        return 0;
  }
  
  int gpio_free(unsigned gpio)
  {
+       unsigned int port = GPIO_TO_PORT(gpio);
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
+               return -1;
+       }
        return 0;
  }
  
@@@ -147,176 -152,3 +165,176 @@@ int gpio_direction_output(unsigned gpio
  
        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
diff --combined drivers/i2c/Kconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,0000000000000000000000000000000000000000..e059df992a19f05c849d0a5c5fb5550074fedfc8
mode 100644,000000..100644
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++menuconfig SYS_I2C
++      bool "I2C device support"
++
++if SYS_I2C
++
++config HARD_I2C
++      bool
++
++config SYS_I2C_MXC
++      bool "Freescale i.MX I2C controller"
++      select HARD_I2C
++      select I2C_QUIRK_REG if FSL_LSCH3 || LS102XA
++
++endif
diff --combined drivers/misc/fsl_iim.c
index 36433a74f85f37e2f7877856853328d3d38527cf,588bfda09f9b4cbf7dabc18cf35ab76126ea21e7..df3885041e5cd129802fceb1efe08831b1b176ad
@@@ -16,9 -16,6 +16,9 @@@
  #ifndef CONFIG_MPC512X
  #include <asm/arch/imx-regs.h>
  #endif
 +#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
 +#include <asm/arch/clock.h>
 +#endif
  
  /* FSL IIM-specific constants */
  #define STAT_BUSY             0x80
@@@ -89,17 -86,13 +89,17 @@@ struct fsl_iim 
        u32 sdat;
        u32 prev;
        u32 srev;
-       u32 prg_p;
+       u32 preg_p;
        u32 scs[0x1f5];
        struct {
                u32 word[0x100];
        } bank[8];
  };
  
 +#if !defined(CONFIG_MX51) && !defined(CONFIG_MX53)
 +#define enable_efuse_prog_supply(enable)
 +#endif
 +
  static int prepare_access(struct fsl_iim **regs, u32 bank, u32 word, int assert,
                                const char *caller)
  {
@@@ -169,7 -162,7 +169,7 @@@ static void direct_access(struct fsl_ii
        iim_write32(&regs->ua, bank << 3 | word >> 5);
        iim_write32(&regs->la, (word << 3 | bit) & 0xff);
        if (fctl == FCTL_PRG)
-               iim_write32(&regs->prg_p, 0xaa);
+               iim_write32(&regs->preg_p, 0xaa);
        iim_setbits32(&regs->fctl, fctl);
        while (iim_read32(&regs->stat) & STAT_BUSY)
                udelay(20);
@@@ -208,7 -201,7 +208,7 @@@ static int prog_bit(struct fsl_iim *reg
  
        clear_status(regs);
        direct_access(regs, bank, word, bit, FCTL_PRG, &stat, &err);
-       iim_write32(&regs->prg_p, 0x00);
+       iim_write32(&regs->preg_p, 0x00);
  
        if (err & ERR_PRGE) {
                puts("fsl_iim fuse_prog(): Program error\n");
@@@ -244,16 -237,12 +244,16 @@@ int fuse_prog(u32 bank, u32 word, u32 v
        if (ret)
                return ret;
  
 +      enable_efuse_prog_supply(1);
        for (bit = 0; val; bit++, val >>= 1)
                if (val & 0x01) {
                        ret = prog_bit(regs, bank, word, bit);
 -                      if (ret)
 +                      if (ret) {
 +                              enable_efuse_prog_supply(0);
                                return ret;
 +                      }
                }
 +      enable_efuse_prog_supply(0);
  
        return 0;
  }
diff --combined drivers/mmc/Kconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,0000000000000000000000000000000000000000..699f861843b540c960435e571885624c6d2ecf34
mode 100644,000000..100644
--- /dev/null
@@@ -1,0 -1,0 +1,23 @@@
++menuconfig MMC
++      bool "MMC/SD device support"
++      select CMD_MMC
++
++if MMC
++
++config GENERIC_MMC
++      bool
++
++config FSL_ESDHC
++      bool "Freescale ESDHC controller"
++      select GENERIC_MMC
++
++config FSL_USDHC
++      bool "Support USDHC"
++      depends on MX6Q
++      depends on FSL_ESDHC
++
++config SUPPORT_EMMC_BOOT
++      bool "Support boot from eMMC"
++      depends on MMC
++
++endif
diff --combined drivers/mmc/fsl_esdhc.c
index c55eb28217bc5920c3137016dc71b8a6cd58b4b4,36ec9128697d9cd489b732c0a2614d7f107c49ba..57efda23e1f3e61a99da0d944b1e2f7cdf60f929
  
  DECLARE_GLOBAL_DATA_PTR;
  
 +#define SDHCI_IRQ_EN_BITS             (IRQSTATEN_CC | IRQSTATEN_TC | \
 +                              IRQSTATEN_CINT | \
 +                              IRQSTATEN_CTOE | IRQSTATEN_CCE | IRQSTATEN_CEBE | \
 +                              IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \
 +                              IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
 +                              IRQSTATEN_DINT)
 +
  struct fsl_esdhc {
 -      uint    dsaddr;
 -      uint    blkattr;
 -      uint    cmdarg;
 -      uint    xfertyp;
 -      uint    cmdrsp0;
 -      uint    cmdrsp1;
 -      uint    cmdrsp2;
 -      uint    cmdrsp3;
 -      uint    datport;
 -      uint    prsstat;
 -      uint    proctl;
 -      uint    sysctl;
 -      uint    irqstat;
 -      uint    irqstaten;
 -      uint    irqsigen;
 -      uint    autoc12err;
 -      uint    hostcapblt;
 -      uint    wml;
 -      uint    mixctrl;
 -      char    reserved1[4];
 -      uint    fevt;
 -      char    reserved2[168];
 -      uint    hostver;
 -      char    reserved3[780];
 -      uint    scr;
 +      uint    dsaddr;         /* SDMA system address register */
 +      uint    blkattr;        /* Block attributes register */
 +      uint    cmdarg;         /* Command argument register */
 +      uint    xfertyp;        /* Transfer type register */
 +      uint    cmdrsp0;        /* Command response 0 register */
 +      uint    cmdrsp1;        /* Command response 1 register */
 +      uint    cmdrsp2;        /* Command response 2 register */
 +      uint    cmdrsp3;        /* Command response 3 register */
 +      uint    datport;        /* Buffer data port register */
 +      uint    prsstat;        /* Present state register */
 +      uint    proctl;         /* Protocol control register */
 +      uint    sysctl;         /* System Control Register */
 +      uint    irqstat;        /* Interrupt status register */
 +      uint    irqstaten;      /* Interrupt status enable register */
 +      uint    irqsigen;       /* Interrupt signal enable register */
 +      uint    autoc12err;     /* Auto CMD error status register */
 +      uint    hostcapblt;     /* Host controller capabilities register */
 +      uint    wml;            /* Watermark level register */
 +      uint    mixctrl;        /* For USDHC */
 +      char    reserved1[4];   /* reserved */
 +      uint    fevt;           /* Force event register */
 +      uint    admaes;         /* ADMA error status register */
 +      uint    adsaddr;        /* ADMA system address register */
 +      char    reserved2[160]; /* reserved */
 +      uint    hostver;        /* Host controller version register */
 +      char    reserved3[4];   /* reserved */
 +      uint    dmaerraddr;     /* DMA error address register */
 +      char    reserved4[4];   /* reserved */
 +      uint    dmaerrattr;     /* DMA error attribute register */
 +      char    reserved5[4];   /* reserved */
 +      uint    hostcapblt2;    /* Host controller capabilities register 2 */
 +      char    reserved6[8];   /* reserved */
 +      uint    tcr;            /* Tuning control register */
 +      char    reserved7[28];  /* reserved */
 +      uint    sddirctl;       /* SD direction control register */
 +      char    reserved8[712]; /* reserved */
 +      uint    scr;            /* eSDHC control register */
  };
  
  /* Return the XFERTYP flags for a given command and data packet */
@@@ -103,7 -84,7 +103,7 @@@ static uint esdhc_xfertyp(struct mmc_cm
        else if (cmd->resp_type & MMC_RSP_PRESENT)
                xfertyp |= XFERTYP_RSPTYP_48;
  
 -#if defined(CONFIG_MX53) || defined(CONFIG_T4240QDS)
 +#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || defined(CONFIG_LS102XA)
        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
                xfertyp |= XFERTYP_CMDTYP_ABORT;
  #endif
@@@ -118,57 -99,69 +118,69 @@@ static voi
  esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
  {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        uint blocks;
        char *buffer;
        uint databuf;
        uint size;
-       uint irqstat;
        uint timeout;
+       int wml = esdhc_read32(&regs->wml);
  
        if (data->flags & MMC_DATA_READ) {
+               wml &= WML_RD_WML_MASK;
                blocks = data->blocks;
                buffer = data->dest;
                while (blocks) {
                        timeout = PIO_TIMEOUT;
                        size = data->blocksize;
-                       irqstat = esdhc_read32(&regs->irqstat);
-                       while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
-                               && --timeout);
-                       if (timeout <= 0) {
-                               printf("\nData Read Failed in PIO Mode.");
-                               return;
-                       }
-                       while (size && (!(irqstat & IRQSTAT_TC))) {
-                               udelay(100); /* Wait before last byte transfer complete */
-                               irqstat = esdhc_read32(&regs->irqstat);
-                               databuf = in_le32(&regs->datport);
-                               *((uint *)buffer) = databuf;
-                               buffer += 4;
-                               size -= 4;
+                       while (size &&
+                               !(esdhc_read32(&regs->irqstat) & IRQSTAT_TC)) {
+                               int i;
+                               u32 prsstat;
+                               while (!((prsstat = esdhc_read32(&regs->prsstat)) &
+                                               PRSSTAT_BREN) && --timeout)
+                                       /* NOP */;
+                               if (!(prsstat & PRSSTAT_BREN)) {
+                                       printf("%s: Data Read Failed in PIO Mode\n",
+                                               __func__);
+                                       return;
+                               }
+                               for (i = 0; i < wml && size; i++) {
+                                       databuf = in_le32(&regs->datport);
+                                       memcpy(buffer, &databuf, sizeof(databuf));
+                                       buffer += 4;
+                                       size -= 4;
+                               }
                        }
                        blocks--;
                }
        } else {
+               wml = (wml & WML_WR_WML_MASK) >> 16;
                blocks = data->blocks;
-               buffer = (char *)data->src;
+               buffer = (char *)data->src; /* cast away 'const' */
                while (blocks) {
                        timeout = PIO_TIMEOUT;
                        size = data->blocksize;
-                       irqstat = esdhc_read32(&regs->irqstat);
-                       while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
-                               && --timeout);
-                       if (timeout <= 0) {
-                               printf("\nData Write Failed in PIO Mode.");
-                               return;
-                       }
-                       while (size && (!(irqstat & IRQSTAT_TC))) {
-                               udelay(100); /* Wait before last byte transfer complete */
-                               databuf = *((uint *)buffer);
-                               buffer += 4;
-                               size -= 4;
-                               irqstat = esdhc_read32(&regs->irqstat);
-                               out_le32(&regs->datport, databuf);
+                       while (size &&
+                               !(esdhc_read32(&regs->irqstat) & IRQSTAT_TC)) {
+                               int i;
+                               u32 prsstat;
+                               while (!((prsstat = esdhc_read32(&regs->prsstat)) &
+                                               PRSSTAT_BWEN) && --timeout)
+                                       /* NOP */;
+                               if (!(prsstat & PRSSTAT_BWEN)) {
+                                       printf("%s: Data Write Failed in PIO Mode\n",
+                                               __func__);
+                                       return;
+                               }
+                               for (i = 0; i < wml && size; i++) {
+                                       memcpy(&databuf, buffer, sizeof(databuf));
+                                       out_le32(&regs->datport, databuf);
+                                       buffer += 4;
+                                       size -= 4;
+                               }
                        }
                        blocks--;
                }
@@@ -180,41 -173,45 +192,42 @@@ static int esdhc_setup_data(struct mmc 
  {
        int timeout;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
 -#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
        uint wml_value;
  
-       wml_value = data->blocksize/4;
+       wml_value = data->blocksize / 4;
  
        if (data->flags & MMC_DATA_READ) {
                if (wml_value > WML_RD_WML_MAX)
                        wml_value = WML_RD_WML_MAX_VAL;
  
                esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
                esdhc_write32(&regs->dsaddr, (u32)data->dest);
 +#endif
        } else {
 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
 +              flush_dcache_range((ulong)data->src,
 +                                 (ulong)data->src+data->blocks
 +                                       *data->blocksize);
 +#endif
                if (wml_value > WML_WR_WML_MAX)
                        wml_value = WML_WR_WML_MAX_VAL;
                if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
-                       printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
-                       return TIMEOUT;
+                       printf("The SD card is locked. Can not write to a locked card.\n");
+                       return UNUSABLE_ERR;
                }
  
+               flush_dcache_range((unsigned long)data->src,
+                               (unsigned long)data->src + data->blocks * data->blocksize);
                esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
                                        wml_value << 16);
 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
                esdhc_write32(&regs->dsaddr, (u32)data->src);
 +#endif
        }
 -#else /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
 -      if (!(data->flags & MMC_DATA_READ)) {
 -              if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
 -                      printf("The SD card is locked. Can not write to a locked card.\n");
 -                      return UNUSABLE_ERR;
 -              }
 -              esdhc_write32(&regs->dsaddr, (u32)data->src);
 -      } else {
 -              esdhc_write32(&regs->dsaddr, (u32)data->dest);
 -      }
 -#endif        /* CONFIG_SYS_FSL_ESDHC_USE_PIO */
  
-       esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+       esdhc_write32(&regs->blkattr, (data->blocks << 16) | data->blocksize);
  
        /* Calculate the timeout period for data transactions */
        /*
         * 2)Timeout period should be minimum 0.250sec as per SD Card spec
         *  So, Number of SD Clock cycles for 0.25sec should be minimum
         *              (SD Clock/sec * 0.25 sec) SD Clock cycles
 -       *              = (mmc->tran_speed * 1/4) SD Clock cycles
 +       *              = (mmc->clock * 1/4) SD Clock cycles
         * As 1) >=  2)
 -       * => (2^(timeout+13)) >= mmc->tran_speed * 1/4
 +       * => (2^(timeout+13)) >= mmc->clock * 1/4
         * Taking log2 both the sides
 -       * => timeout + 13 >= log2(mmc->tran_speed/4)
 +       * => timeout + 13 >= log2(mmc->clock/4)
         * Rounding up to next power of 2
 -       * => timeout + 13 = log2(mmc->tran_speed/4) + 1
 -       * => timeout + 13 = fls(mmc->tran_speed/4)
 +       * => timeout + 13 = log2(mmc->clock/4) + 1
 +       * => timeout + 13 = fls(mmc->clock/4)
         */
 -      timeout = fls(mmc->tran_speed / 4);
 +      timeout = fls(mmc->clock/4);
        timeout -= 13;
  
        if (timeout > 14)
                timeout = 14;
-       if (timeout < 0)
+       else if (timeout < 0)
                timeout = 0;
  
  #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
        if ((timeout == 4) || (timeout == 8) || (timeout == 12))
                timeout++;
  #endif
 +
 +#ifdef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
 +      timeout = 0xE;
 +#endif
        esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
  
        return 0;
  }
  
 -static inline void check_and_invalidate_dcache_range(struct mmc_cmd *cmd,
 -                                      struct mmc_data *data)
 -{
 -      unsigned long start = (unsigned long)data->dest;
 -      size_t start_ofs = start & (ARCH_DMA_MINALIGN - 1);
 -      unsigned long size = data->blocks * data->blocksize;
 -      unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN);
 -
 -      start -= start_ofs;
 +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
 +static void check_and_invalidate_dcache_range
 +      (struct mmc_cmd *cmd,
 +       struct mmc_data *data) {
 +      unsigned start = (unsigned)data->dest ;
 +      unsigned size = roundup(ARCH_DMA_MINALIGN,
 +                              data->blocks*data->blocksize);
 +      unsigned end = start+size ;
        invalidate_dcache_range(start, end);
  }
 +#endif
  
  /*
   * Sends a command out on the bus.  Takes the mmc pointer,
  static int
  esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
  {
 +      int     err = 0;
        uint    xfertyp;
        uint    irqstat;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       volatile struct fsl_esdhc *regs = cfg->esdhc_base;
+       unsigned long start;
  
  #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
                return 0;
  #endif
        esdhc_write32(&regs->irqstat, -1);
  
        sync();
  
+       start = get_timer_masked();
        /* Wait for the bus to be idle */
        while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
-                       (esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
-               ;
+               (esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB)) {
+               if (get_timer(start) > CONFIG_SYS_HZ) {
+                       printf("%s: Timeout waiting for bus idle\n", __func__);
+                       return TIMEOUT;
+               }
+       }
  
-       while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
-               ;
+       start = get_timer_masked();
+       while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA) {
+               if (get_timer(start) > CONFIG_SYS_HZ)
+                       return TIMEOUT;
+       }
  
        /* Wait at least 8 SD clock cycles before the next command */
        /*
  
        /* Set up for a data transfer if we have one */
        if (data) {
 -              int err;
 -
                err = esdhc_setup_data(mmc, data);
-               if(err)
+               if (err)
                        return err;
        }
  
        esdhc_write32(&regs->cmdarg, cmd->cmdarg);
  #if defined(CONFIG_FSL_USDHC)
        esdhc_write32(&regs->mixctrl,
-       (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
+       (esdhc_read32(&regs->mixctrl) & ~0x7f) | (xfertyp & 0x7F));
        esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
  #else
        esdhc_write32(&regs->xfertyp, xfertyp);
  #endif
  
+       /* Mask all irqs */
+       esdhc_write32(&regs->irqsigen, 0);
+       start = get_timer_masked();
        /* Wait for the command to complete */
-       while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
-               ;
+       while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) {
+               if (get_timer(start) > CONFIG_SYS_HZ) {
+                       printf("%s: Timeout waiting for cmd completion\n", __func__);
+                       return TIMEOUT;
+               }
+       }
+       if (data && (data->flags & MMC_DATA_READ))
+               check_and_invalidate_dcache_range(cmd, data);
  
        irqstat = esdhc_read32(&regs->irqstat);
  
 -      /* Reset CMD and DATA portions on error */
 -      if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
 -              esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
 -                            SYSCTL_RSTC);
 -              start = get_timer_masked();
 -              while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC) {
 -                      if (get_timer(start) > CONFIG_SYS_HZ)
 -                              return TIMEOUT;
 -              }
 -
 -              if (data) {
 -                      esdhc_write32(&regs->sysctl,
 -                                    esdhc_read32(&regs->sysctl) |
 -                                    SYSCTL_RSTD);
 -                      start = get_timer_masked();
 -                      while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD)) {
 -                              if (get_timer(start) > CONFIG_SYS_HZ)
 -                                      return TIMEOUT;
 -                      }
 -              }
 +      if (irqstat & CMD_ERR) {
 +              err = COMM_ERR;
 +              goto out;
        }
  
 -      if (irqstat & CMD_ERR)
 -              return COMM_ERR;
 -
 -      if (irqstat & IRQSTAT_CTOE)
 -              return TIMEOUT;
 +      if (irqstat & IRQSTAT_CTOE) {
 +              err = TIMEOUT;
 +              goto out;
 +      }
  
        /* Workaround for ESDHC errata ENGcm03648 */
        if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
  
                if (timeout <= 0) {
                        printf("Timeout waiting for DAT0 to go high!\n");
 -                      return TIMEOUT;
 +                      err = TIMEOUT;
 +                      goto out;
                }
        }
  
  #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
                esdhc_pio_read_write(mmc, data);
  #else
 -              unsigned long start = get_timer_masked();
 -              unsigned long data_timeout = data->blocks *
 -                      data->blocksize * 100 / mmc->bus_width /
 -                      (mmc->tran_speed / CONFIG_SYS_HZ) + CONFIG_SYS_HZ;
 -
                do {
                        irqstat = esdhc_read32(&regs->irqstat);
  
                        if (irqstat & IRQSTAT_DTOE) {
 -                              printf("MMC/SD data %s timeout\n",
 -                                      data->flags & MMC_DATA_READ ?
 -                                      "read" : "write");
 -                              return TIMEOUT;
 +                              err = TIMEOUT;
 +                              goto out;
                        }
  
                        if (irqstat & DATA_ERR) {
 -                              printf("MMC/SD data error\n");
 -                              return COMM_ERR;
 -                      }
 -
 -                      if (get_timer(start) > data_timeout) {
 -                              printf("MMC/SD timeout waiting for %s xfer completion\n",
 -                                              data->flags & MMC_DATA_READ ?
 -                                              "read" : "write");
 -                              return TIMEOUT;
 +                              err = COMM_ERR;
 +                              goto out;
                        }
 -              } while (!(irqstat & IRQSTAT_TC) &&
 -                      (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
 +              } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
  
 -              check_and_invalidate_dcache_range(cmd, data);
 +              if (data->flags & MMC_DATA_READ)
 +                      check_and_invalidate_dcache_range(cmd, data);
  #endif
        }
  
-       esdhc_write32(&regs->irqstat, -1);
 +out:
 +      /* Reset CMD and DATA portions on error */
 +      if (err) {
 +              esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
 +                            SYSCTL_RSTC);
 +              while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
 +                      ;
 +
 +              if (data) {
 +                      esdhc_write32(&regs->sysctl,
 +                                    esdhc_read32(&regs->sysctl) |
 +                                    SYSCTL_RSTD);
 +                      while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
 +                              ;
 +              }
 +      }
 +
+       esdhc_write32(&regs->irqstat, irqstat);
  
 -      return 0;
 +      return err;
  }
  
  static void set_sysctl(struct mmc *mmc, uint clock)
  {
        int div, pre_div;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       volatile struct fsl_esdhc *regs = cfg->esdhc_base;
        int sdhc_clk = cfg->sdhc_clk;
        uint clk;
  
 -      if (clock < mmc->f_min)
 -              clock = mmc->f_min;
 +      if (clock < mmc->cfg->f_min)
 +              clock = mmc->cfg->f_min;
  
        if (sdhc_clk / 16 > clock) {
                for (pre_div = 2; pre_div < 256; pre_div *= 2)
  static void esdhc_set_ios(struct mmc *mmc)
  {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
  
        /* Set the clock speed */
        set_sysctl(mmc, mmc->clock);
  static int esdhc_init(struct mmc *mmc)
  {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        int timeout = 1000;
  
        /* Reset the entire host controller */
  static int esdhc_getcd(struct mmc *mmc)
  {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        int timeout = 1000;
  
 +#ifdef CONFIG_ESDHC_DETECT_QUIRK
 +      if (CONFIG_ESDHC_DETECT_QUIRK)
 +              return 1;
 +#endif
        while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
                udelay(1000);
  
@@@ -541,13 -563,6 +572,13 @@@ static void esdhc_reset(struct fsl_esdh
                printf("MMC/SD: Reset never completed.\n");
  }
  
 +static const struct mmc_ops esdhc_ops = {
 +      .send_cmd       = esdhc_send_cmd,
 +      .set_ios        = esdhc_set_ios,
 +      .init           = esdhc_init,
 +      .getcd          = esdhc_getcd,
 +};
 +
  int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
  {
        struct fsl_esdhc *regs;
        u32 caps, voltage_caps;
  
        if (!cfg)
-               return -1;
+               return -EINVAL;
  
 -      mmc = kzalloc(sizeof(struct mmc), GFP_KERNEL);
 -      if (!mmc)
 -              return -ENOMEM;
 -
 -      sprintf(mmc->name, "FSL_SDHC");
 -      regs = cfg->esdhc_base;
 +      regs = (struct fsl_esdhc *)cfg->esdhc_base;
  
        /* First reset the eSDHC controller */
        esdhc_reset(regs);
        esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
                                | SYSCTL_IPGEN | SYSCTL_CKEN);
  
 -      mmc->priv = cfg;
 -      mmc->send_cmd = esdhc_send_cmd;
 -      mmc->set_ios = esdhc_set_ios;
 -      mmc->init = esdhc_init;
 -      mmc->getcd = esdhc_getcd;
 -      mmc->getwp = NULL;
 +      writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
 +      memset(&cfg->cfg, 0, sizeof(cfg->cfg));
  
        voltage_caps = 0;
 -      caps = regs->hostcapblt;
 +      caps = esdhc_read32(&regs->hostcapblt);
  
  #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
        caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
                        ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
  #endif
 +
 +/* T4240 host controller capabilities register should have VS33 bit */
 +#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
 +      caps = caps | ESDHC_HOSTCAPBLT_VS33;
 +#endif
 +
        if (caps & ESDHC_HOSTCAPBLT_VS18)
                voltage_caps |= MMC_VDD_165_195;
        if (caps & ESDHC_HOSTCAPBLT_VS30)
        if (caps & ESDHC_HOSTCAPBLT_VS33)
                voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;
  
 +      cfg->cfg.name = "FSL_SDHC";
 +      cfg->cfg.ops = &esdhc_ops;
  #ifdef CONFIG_SYS_SD_VOLTAGE
 -      mmc->voltages = CONFIG_SYS_SD_VOLTAGE;
 +      cfg->cfg.voltages = CONFIG_SYS_SD_VOLTAGE;
  #else
 -      mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 +      cfg->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
  #endif
 -      if ((mmc->voltages & voltage_caps) == 0) {
 +      if ((cfg->cfg.voltages & voltage_caps) == 0) {
                printf("voltage not supported by controller\n");
-               return -1;
+               return -EINVAL;
        }
  
 -      mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
 +      cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
  
        if (cfg->max_bus_width > 0) {
                if (cfg->max_bus_width < 8)
 -                      mmc->host_caps &= ~MMC_MODE_8BIT;
 +                      cfg->cfg.host_caps &= ~MMC_MODE_8BIT;
                if (cfg->max_bus_width < 4)
 -                      mmc->host_caps &= ~MMC_MODE_4BIT;
 +                      cfg->cfg.host_caps &= ~MMC_MODE_4BIT;
        }
  
        if (caps & ESDHC_HOSTCAPBLT_HSS)
 -              mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 +              cfg->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 +
 +#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
 +      if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
 +              cfg->cfg.host_caps &= ~MMC_MODE_8BIT;
 +#endif
 +
 +      cfg->cfg.f_min = 400000;
 +      cfg->cfg.f_max = min(cfg->sdhc_clk, (u32)52000000);
  
 -      mmc->f_min = 400000;
 -      mmc->f_max = MIN(cfg->sdhc_clk, 52000000);
 +      cfg->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  
 -      mmc->b_max = 0;
 -      mmc_register(mmc);
 +      mmc = mmc_create(&cfg->cfg, cfg);
 +      if (mmc == NULL)
 +              return -1;
  
        return 0;
  }
@@@ -633,8 -641,10 +664,10 @@@ int fsl_esdhc_mmc_init(bd_t *bis
  {
        struct fsl_esdhc_cfg *cfg;
  
-       cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
-       cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
+       cfg = kzalloc(sizeof(struct fsl_esdhc_cfg), GFP_KERNEL);
+       if (!cfg)
+               return -ENOMEM;
+       cfg->esdhc_base = (void __iomem *)CONFIG_SYS_FSL_ESDHC_ADDR;
        cfg->sdhc_clk = gd->arch.sdhc_clk;
        return fsl_esdhc_initialize(bis, cfg);
  }
diff --combined drivers/mmc/mmc.c
index 1eb9c2733948bf954aa00414824aa491adc4a4e3,cc998b2039c3dcfae2e4f36044bf9cfb40599d21..88c0206b1a92c795640a5da00f2cbdd7f300cb8c
  #include <config.h>
  #include <common.h>
  #include <command.h>
 +#include <errno.h>
  #include <mmc.h>
  #include <part.h>
  #include <malloc.h>
  #include <linux/list.h>
  #include <div64.h>
 -
 -/* Set block count limit because of 16 bit register limit on some hardware*/
 -#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
 -#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
 -#endif
 +#include "mmc_private.h"
  
  static struct list_head mmc_devices;
  static int cur_dev_num = -1;
  
 -int __weak board_mmc_getwp(struct mmc *mmc)
 +__weak int board_mmc_getwp(struct mmc *mmc)
  {
        return -1;
  }
@@@ -33,8 -36,8 +33,8 @@@ int mmc_getwp(struct mmc *mmc
        wp = board_mmc_getwp(mmc);
  
        if (wp < 0) {
 -              if (mmc->getwp)
 -                      wp = mmc->getwp(mmc);
 +              if (mmc->cfg->ops->getwp)
 +                      wp = mmc->cfg->ops->getwp(mmc);
                else
                        wp = 0;
        }
        return wp;
  }
  
 -int __board_mmc_getcd(struct mmc *mmc) {
 +__weak int board_mmc_getcd(struct mmc *mmc)
 +{
        return -1;
  }
  
 -int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
 -      alias("__board_mmc_getcd")));
 -
 -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 -                      struct mmc_data *data)
 +int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
  {
 -      struct mmc_data backup;
        int ret;
  
 -      memset(&backup, 0, sizeof(backup));
 -
  #ifdef CONFIG_MMC_TRACE
        int i;
        u8 *ptr;
  
        printf("CMD_SEND:%d\n", cmd->cmdidx);
        printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
 -      ret = mmc->send_cmd(mmc, cmd, data);
 +      ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
        switch (cmd->resp_type) {
                case MMC_RSP_NONE:
                        printf("\t\tMMC_RSP_NONE\n");
                        break;
        }
  #else
 -      ret = mmc->send_cmd(mmc, cmd, data);
 +      ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
  #endif
        return ret;
  }
  
 -static int mmc_send_status(struct mmc *mmc, int timeout)
 +int mmc_send_status(struct mmc *mmc, int timeout)
  {
        struct mmc_cmd cmd;
        int err, retries = 5;
                             MMC_STATE_PRG)
                                break;
                        else if (cmd.response[0] & MMC_STATUS_MASK) {
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                                printf("Status Error: 0x%08X\n",
                                        cmd.response[0]);
 +#endif
                                return COMM_ERR;
                        }
                } else if (--retries < 0)
        printf("CURR STATE:%d\n", status);
  #endif
        if (timeout <= 0) {
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("Timeout waiting card ready\n");
 +#endif
                return TIMEOUT;
        }
 +      if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
 +              return SWITCH_ERR;
  
        return 0;
  }
  
 -static int mmc_set_blocklen(struct mmc *mmc, int len)
 +int mmc_set_blocklen(struct mmc *mmc, int len)
  {
        struct mmc_cmd cmd;
  
 +      if (mmc->ddr_mode)
 +              return 0;
 +
        cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
        cmd.resp_type = MMC_RSP_R1;
        cmd.cmdarg = len;
@@@ -181,13 -181,179 +181,13 @@@ struct mmc *find_mmc_device(int dev_num
                        return m;
        }
  
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
        printf("MMC Device %d not found\n", dev_num);
 +#endif
  
        return NULL;
  }
  
 -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
 -{
 -      struct mmc_cmd cmd;
 -      ulong end;
 -      int err, start_cmd, end_cmd;
 -
 -      if (mmc->high_capacity)
 -              end = start + blkcnt - 1;
 -      else {
 -              end = (start + blkcnt - 1) * mmc->write_bl_len;
 -              start *= mmc->write_bl_len;
 -      }
 -
 -      if (IS_SD(mmc)) {
 -              start_cmd = SD_CMD_ERASE_WR_BLK_START;
 -              end_cmd = SD_CMD_ERASE_WR_BLK_END;
 -      } else {
 -              start_cmd = MMC_CMD_ERASE_GROUP_START;
 -              end_cmd = MMC_CMD_ERASE_GROUP_END;
 -      }
 -
 -      cmd.cmdidx = start_cmd;
 -      cmd.cmdarg = start;
 -      cmd.resp_type = MMC_RSP_R1;
 -
 -      err = mmc_send_cmd(mmc, &cmd, NULL);
 -      if (err)
 -              goto err_out;
 -
 -      cmd.cmdidx = end_cmd;
 -      cmd.cmdarg = end;
 -
 -      err = mmc_send_cmd(mmc, &cmd, NULL);
 -      if (err)
 -              goto err_out;
 -
 -      cmd.cmdidx = MMC_CMD_ERASE;
 -      cmd.cmdarg = SECURE_ERASE;
 -      cmd.resp_type = MMC_RSP_R1b;
 -
 -      err = mmc_send_cmd(mmc, &cmd, NULL);
 -      if (err)
 -              goto err_out;
 -
 -      return 0;
 -
 -err_out:
 -      puts("mmc erase failed\n");
 -      return err;
 -}
 -
 -static unsigned long
 -mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
 -{
 -      int err = 0;
 -      struct mmc *mmc = find_mmc_device(dev_num);
 -      lbaint_t blk = 0, blk_r = 0;
 -      int timeout = 1000;
 -
 -      if (!mmc)
 -              return -1;
 -
 -      if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
 -              printf("\n\nCaution! Your devices Erase group is 0x%x\n"
 -                     "The erase range would be change to "
 -                     "0x" LBAF "~0x" LBAF "\n\n",
 -                     mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
 -                     ((start + blkcnt + mmc->erase_grp_size)
 -                     & ~(mmc->erase_grp_size - 1)) - 1);
 -
 -      while (blk < blkcnt) {
 -              blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
 -                      mmc->erase_grp_size : (blkcnt - blk);
 -              err = mmc_erase_t(mmc, start + blk, blk_r);
 -              if (err)
 -                      break;
 -
 -              blk += blk_r;
 -
 -              /* Waiting for the ready status */
 -              if (mmc_send_status(mmc, timeout))
 -                      return 0;
 -      }
 -
 -      return blk;
 -}
 -
 -static ulong
 -mmc_write_blocks(struct mmc *mmc, lbaint_t start, lbaint_t blkcnt, const void*src)
 -{
 -      struct mmc_cmd cmd;
 -      struct mmc_data data;
 -      int timeout = 1000;
 -
 -      if ((start + blkcnt) > mmc->block_dev.lba) {
 -              printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
 -                      start + blkcnt, mmc->block_dev.lba);
 -              return 0;
 -      }
 -
 -      if (blkcnt == 0)
 -              return 0;
 -      else if (blkcnt == 1)
 -              cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;
 -      else
 -              cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
 -
 -      if (mmc->high_capacity)
 -              cmd.cmdarg = start;
 -      else
 -              cmd.cmdarg = start * mmc->write_bl_len;
 -
 -      cmd.resp_type = MMC_RSP_R1;
 -
 -      data.src = src;
 -      data.blocks = blkcnt;
 -      data.blocksize = mmc->write_bl_len;
 -      data.flags = MMC_DATA_WRITE;
 -
 -      if (mmc_send_cmd(mmc, &cmd, &data)) {
 -              printf("mmc write failed\n");
 -              return 0;
 -      }
 -
 -      /* SPI multiblock writes terminate using a special
 -       * token, not a STOP_TRANSMISSION request.
 -       */
 -      if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
 -              cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 -              cmd.cmdarg = 0;
 -              cmd.resp_type = MMC_RSP_R1b;
 -              if (mmc_send_cmd(mmc, &cmd, NULL)) {
 -                      printf("mmc fail to send stop cmd\n");
 -                      return 0;
 -              }
 -      }
 -
 -      /* Waiting for the ready status */
 -      if (mmc_send_status(mmc, timeout))
 -              return 0;
 -
 -      return blkcnt;
 -}
 -
 -static ulong
 -mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void*src)
 -{
 -      lbaint_t cur, blocks_todo = blkcnt;
 -
 -      struct mmc *mmc = find_mmc_device(dev_num);
 -      if (!mmc)
 -              return 0;
 -
 -      if (mmc_set_blocklen(mmc, mmc->write_bl_len))
 -              return 0;
 -
 -      do {
 -              cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
 -              if(mmc_write_blocks(mmc, start, cur, src) != cur)
 -                      return 0;
 -              blocks_todo -= cur;
 -              start += cur;
 -              src += cur * mmc->write_bl_len;
 -      } while (blocks_todo > 0);
 -
 -      return blkcnt;
 -}
 -
  static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
                           lbaint_t blkcnt)
  {
                cmd.cmdarg = 0;
                cmd.resp_type = MMC_RSP_R1b;
                if (mmc_send_cmd(mmc, &cmd, NULL)) {
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                        printf("mmc fail to send stop cmd\n");
 +#endif
                        return 0;
                }
        }
@@@ -241,10 -405,8 +241,10 @@@ static ulong mmc_bread(int dev_num, lba
                return 0;
  
        if ((start + blkcnt) > mmc->block_dev.lba) {
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
                        start + blkcnt, mmc->block_dev.lba);
 +#endif
                return 0;
        }
  
                return 0;
  
        do {
 -              cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
 +              cur = (blocks_todo > mmc->cfg->b_max) ?
 +                      mmc->cfg->b_max : blocks_todo;
                if(mmc_read_blocks(mmc, dst, start, cur) != cur)
                        return 0;
                blocks_todo -= cur;
@@@ -312,7 -473,7 +312,7 @@@ static int sd_send_op_cond(struct mmc *
                 * specified.
                 */
                cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
 -                      (mmc->voltages & 0xff8000);
 +                      (mmc->cfg->voltages & 0xff8000);
  
                if (mmc->version == SD_VERSION_2)
                        cmd.cmdarg |= OCR_HCS;
  
                udelay(1000);
        } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
-       if (timeout <= 0)
+       if (!(cmd.response[0] & OCR_BUSY))
                return UNUSABLE_ERR;
  
        if (mmc->version != SD_VERSION_2)
@@@ -361,11 -521,11 +360,11 @@@ static int mmc_send_op_cond_iter(struc
        cmd->cmdarg = 0;
        if (use_arg && !mmc_host_is_spi(mmc)) {
                cmd->cmdarg =
 -                      (mmc->voltages &
 +                      (mmc->cfg->voltages &
                        (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
                        (mmc->op_cond_response & OCR_ACCESS_MODE);
  
 -              if (mmc->host_caps & MMC_MODE_HC)
 +              if (mmc->cfg->host_caps & MMC_MODE_HC)
                        cmd->cmdarg |= OCR_HCS;
        }
        err = mmc_send_cmd(mmc, cmd, NULL);
        return 0;
  }
  
 -int mmc_send_op_cond(struct mmc *mmc)
 +static int mmc_send_op_cond(struct mmc *mmc)
  {
        struct mmc_cmd cmd;
        int err, i;
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
  
-       /* Asking to the card its capabilities */
+       /* Asking to the card its capabilities */
        mmc->op_cond_pending = 1;
        for (i = 0; i < 2; i++) {
                err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
        return IN_PROGRESS;
  }
  
 -int mmc_complete_op_cond(struct mmc *mmc)
 +static int mmc_complete_op_cond(struct mmc *mmc)
  {
        struct mmc_cmd cmd;
        int timeout = 1000;
                if (err)
                        return err;
                if (get_timer(start) > timeout)
-                       return UNUSABLE_ERR;
+                       break;
                udelay(100);
        } while (!(mmc->op_cond_response & OCR_BUSY));
+       if (!(mmc->op_cond_response & OCR_BUSY)) {
+               debug("%s: timeout\n", __func__);
+               return UNUSABLE_ERR;
+       }
  
        if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
                cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
        mmc->ocr = cmd.response[0];
  
        mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
 -      mmc->rca = 0;
 +      mmc->rca = 1;
  
        return 0;
  }
@@@ -486,7 -650,7 +489,7 @@@ static int mmc_change_freq(struct mmc *
        char cardtype;
        int err;
  
 -      mmc->card_caps = 0;
 +      mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
  
        if (mmc_host_is_spi(mmc))
                return 0;
        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
  
        if (err)
 -              return err;
 +              return err == SWITCH_ERR ? 0 : err;
  
        /* Now check to see that it worked */
        err = mmc_send_ext_csd(mmc, ext_csd);
                return 0;
  
        /* High Speed is set, there are two types: 52MHz and 26MHz */
 -      if (cardtype & MMC_HS_52MHZ)
 +      if (cardtype & EXT_CSD_CARD_TYPE_52) {
 +              if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
 +                      mmc->card_caps |= MMC_MODE_DDR_52MHz;
                mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 -      else
 +      } else {
                mmc->card_caps |= MMC_MODE_HS;
 +      }
  
        return 0;
  }
@@@ -557,32 -718,6 +560,32 @@@ static int mmc_set_capacity(struct mmc 
        return 0;
  }
  
 +int mmc_select_hwpart(int dev_num, int hwpart)
 +{
 +      struct mmc *mmc = find_mmc_device(dev_num);
 +      int ret;
 +
 +      if (!mmc)
 +              return -ENODEV;
 +
 +      if (mmc->part_num == hwpart)
 +              return 0;
 +
 +      if (mmc->part_config == MMCPART_NOAVAILABLE) {
 +              printf("Card doesn't support part_switch\n");
 +              return -EMEDIUMTYPE;
 +      }
 +
 +      ret = mmc_switch_part(dev_num, hwpart);
 +      if (ret)
 +              return ret;
 +
 +      mmc->part_num = hwpart;
 +
 +      return 0;
 +}
 +
 +
  int mmc_switch_part(int dev_num, unsigned int part_num)
  {
        struct mmc *mmc = find_mmc_device(dev_num);
        ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
                         (mmc->part_config & ~PART_ACCESS_MASK)
                         | (part_num & PART_ACCESS_MASK));
 -      if (ret)
 -              return ret;
  
 -      return mmc_set_capacity(mmc, part_num);
 +      /*
 +       * Set the capacity if the switch succeeded or was intended
 +       * to return to representing the raw device.
 +       */
 +      if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
 +              ret = mmc_set_capacity(mmc, part_num);
 +
 +      return ret;
  }
  
  int mmc_getcd(struct mmc *mmc)
        cd = board_mmc_getcd(mmc);
  
        if (cd < 0) {
 -              if (mmc->getcd)
 -                      cd = mmc->getcd(mmc);
 +              if (mmc->cfg->ops->getcd)
 +                      cd = mmc->cfg->ops->getcd(mmc);
                else
                        cd = 1;
        }
@@@ -737,8 -867,8 +740,8 @@@ retry_scr
         * This can avoid furthur problem when the card runs in different
         * mode between the host.
         */
 -      if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
 -              (mmc->host_caps & MMC_MODE_HS)))
 +      if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
 +              (mmc->cfg->host_caps & MMC_MODE_HS)))
                return 0;
  
        err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
@@@ -785,17 -915,16 +788,17 @@@ static const int multipliers[] = 
  
  static void mmc_set_ios(struct mmc *mmc)
  {
 -      mmc->set_ios(mmc);
 +      if (mmc->cfg->ops->set_ios)
 +              mmc->cfg->ops->set_ios(mmc);
  }
  
  void mmc_set_clock(struct mmc *mmc, uint clock)
  {
 -      if (clock > mmc->f_max)
 -              clock = mmc->f_max;
 +      if (clock > mmc->cfg->f_max)
 +              clock = mmc->cfg->f_max;
  
 -      if (clock < mmc->f_min)
 -              clock = mmc->f_min;
 +      if (clock < mmc->cfg->f_min)
 +              clock = mmc->cfg->f_min;
  
        mmc->clock = clock;
  
@@@ -912,7 -1041,6 +915,7 @@@ static int mmc_startup(struct mmc *mmc
  
        mmc->tran_speed = freq * mult;
  
 +      mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
        mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
  
        if (IS_SD(mmc))
        if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
                mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
  
 +      if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
 +              cmd.cmdidx = MMC_CMD_SET_DSR;
 +              cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
 +              cmd.resp_type = MMC_RSP_NONE;
 +              if (mmc_send_cmd(mmc, &cmd, NULL))
 +                      printf("MMC: SET_DSR failed\n");
 +      }
 +
        /* Select the card, and put it into Transfer Mode */
        if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
                cmd.cmdidx = MMC_CMD_SELECT_CARD;
                case 6:
                        mmc->version = MMC_VERSION_4_5;
                        break;
 +              case 7:
 +                      mmc->version = MMC_VERSION_5_0;
 +                      break;
                }
  
                /*
 -               * Check whether GROUP_DEF is set, if yes, read out
 -               * group size from ext_csd directly, or calculate
 -               * the group size from the csd value.
 +               * Host needs to enable ERASE_GRP_DEF bit if device is
 +               * partitioned. This bit will be lost every time after a reset
 +               * or power off. This will affect erase size.
                 */
 -              if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
 +              if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
 +                  (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
 +                      err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
 +                              EXT_CSD_ERASE_GROUP_DEF, 1);
 +
 +                      if (err)
 +                              return err;
 +                      else
 +                              ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
 +
 +                      /* Read out group size from ext_csd */
                        mmc->erase_grp_size =
                                ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
                                        MMC_MAX_BLOCK_LEN * 1024;
 +                      /*
 +                       * if high capacity and partition setting completed
 +                       * SEC_COUNT is valid even if it is smaller than 2 GiB
 +                       * JEDEC Standard JESD84-B45, 6.2.4
 +                       */
 +                      if (mmc->high_capacity &&
 +                          (ext_csd[EXT_CSD_PARTITION_SETTING] &
 +                           EXT_CSD_PARTITION_SETTING_COMPLETED)) {
 +                              capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
 +                                      (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
 +                                      (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
 +                                      (ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
 +                              capacity *= MMC_MAX_BLOCK_LEN;
 +                              mmc->capacity_user = capacity;
 +                      }
                } else {
 +                      /* Calculate the group size from the csd value. */
                        int erase_gsz, erase_gmul;
                        erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
                        erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
                return err;
  
        /* Restrict card's capabilities by what the host can do */
 -      mmc->card_caps &= mmc->host_caps;
 +      mmc->card_caps &= mmc->cfg->host_caps;
  
        if (IS_SD(mmc)) {
                if (mmc->card_caps & MMC_MODE_4BIT) {
  
                /* An array of possible bus widths in order of preference */
                static unsigned ext_csd_bits[] = {
 +                      EXT_CSD_DDR_BUS_WIDTH_8,
 +                      EXT_CSD_DDR_BUS_WIDTH_4,
                        EXT_CSD_BUS_WIDTH_8,
                        EXT_CSD_BUS_WIDTH_4,
                        EXT_CSD_BUS_WIDTH_1,
  
                /* An array to map CSD bus widths to host cap bits */
                static unsigned ext_to_hostcaps[] = {
 +                      [EXT_CSD_DDR_BUS_WIDTH_4] =
 +                              MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
 +                      [EXT_CSD_DDR_BUS_WIDTH_8] =
 +                              MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
                        [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
                        [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
                };
  
                /* An array to map chosen bus width to an integer */
                static unsigned widths[] = {
 -                      8, 4, 1,
 +                      8, 4, 8, 4, 1,
                };
  
                for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
                        unsigned int extw = ext_csd_bits[idx];
 +                      unsigned int caps = ext_to_hostcaps[extw];
  
                        /*
 -                       * Check to make sure the controller supports
 -                       * this bus width, if it's more than 1
 +                       * Check to make sure the card and controller support
 +                       * these capabilities
                         */
 -                      if (extw != EXT_CSD_BUS_WIDTH_1 &&
 -                                      !(mmc->host_caps & ext_to_hostcaps[extw]))
 +                      if ((mmc->card_caps & caps) != caps)
                                continue;
  
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
                        if (err)
                                continue;
  
 +                      mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
                        mmc_set_bus_width(mmc, widths[idx]);
  
                        err = mmc_send_ext_csd(mmc, test_csd);
 -                      if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
 -                                  == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
 -                               && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
 -                                  == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
 -                               && ext_csd[EXT_CSD_REV] \
 -                                  == test_csd[EXT_CSD_REV]
 -                               && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
 -                                  == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
 -                               && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
 -                                      &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
 -
 -                              mmc->card_caps |= ext_to_hostcaps[extw];
 +
 +                      if (err)
 +                              continue;
 +
 +                      /* Only compare read only fields */
 +                      if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
 +                              == test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
 +                          ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
 +                              == test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
 +                          ext_csd[EXT_CSD_REV]
 +                              == test_csd[EXT_CSD_REV] &&
 +                          ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
 +                              == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
 +                          memcmp(&ext_csd[EXT_CSD_SEC_CNT],
 +                                 &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
                                break;
 -                      }
 +                      else
 +                              err = SWITCH_ERR;
                }
  
 +              if (err)
 +                      return err;
 +
                if (mmc->card_caps & MMC_MODE_HS) {
                        if (mmc->card_caps & MMC_MODE_HS_52MHz)
                                mmc->tran_speed = 52000000;
  
        mmc_set_clock(mmc, mmc->tran_speed);
  
 +      /* Fix the block length for DDR mode */
 +      if (mmc->ddr_mode) {
 +              mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
 +              mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
 +      }
 +
        /* fill in device description */
        mmc->block_dev.lun = 0;
        mmc->block_dev.type = 0;
        mmc->block_dev.blksz = mmc->read_bl_len;
        mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
        mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
        sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
                mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
                (mmc->cid[3] >> 16) & 0xffff);
                (mmc->cid[2] >> 24) & 0xff);
        sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
                (mmc->cid[2] >> 16) & 0xf);
 +#else
 +      mmc->block_dev.vendor[0] = 0;
 +      mmc->block_dev.product[0] = 0;
 +      mmc->block_dev.revision[0] = 0;
 +#endif
  #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
        init_part(&mmc->block_dev);
  #endif
@@@ -1229,7 -1294,7 +1232,7 @@@ static int mmc_send_if_cond(struct mmc 
  
        cmd.cmdidx = SD_CMD_SEND_IF_COND;
        /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
 -      cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
 +      cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
        cmd.resp_type = MMC_RSP_R7;
  
        err = mmc_send_cmd(mmc, &cmd, NULL);
        return 0;
  }
  
 -int mmc_register(struct mmc *mmc)
 +/* not used any more */
 +int __deprecated mmc_register(struct mmc *mmc)
 +{
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 +      printf("%s is deprecated! use mmc_create() instead.\n", __func__);
 +#endif
 +      return -1;
 +}
 +
 +struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
  {
 +      struct mmc *mmc;
 +
 +      /* quick validation */
 +      if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
 +                      cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
 +              return NULL;
 +
 +      mmc = calloc(1, sizeof(*mmc));
 +      if (mmc == NULL)
 +              return NULL;
 +
 +      mmc->cfg = cfg;
 +      mmc->priv = priv;
 +
 +      /* the following chunk was mmc_register() */
 +
 +      /* Setup dsr related values */
 +      mmc->dsr_imp = 0;
 +      mmc->dsr = 0xffffffff;
        /* Setup the universal parts of the block interface just once */
        mmc->block_dev.if_type = IF_TYPE_MMC;
        mmc->block_dev.dev = cur_dev_num++;
        mmc->block_dev.block_read = mmc_bread;
        mmc->block_dev.block_write = mmc_bwrite;
        mmc->block_dev.block_erase = mmc_berase;
 -      if (!mmc->b_max)
 -              mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  
 -      INIT_LIST_HEAD (&mmc->link);
 +      /* setup initial part type */
 +      mmc->block_dev.part_type = mmc->cfg->part_type;
  
 -      list_add_tail (&mmc->link, &mmc_devices);
 +      INIT_LIST_HEAD(&mmc->link);
  
 -      return 0;
 +      list_add_tail(&mmc->link, &mmc_devices);
 +
 +      return mmc;
 +}
 +
 +void mmc_destroy(struct mmc *mmc)
 +{
 +      /* only freeing memory for now */
 +      free(mmc);
  }
  
  #ifdef CONFIG_PARTITIONS
@@@ -1310,36 -1340,24 +1313,36 @@@ block_dev_desc_t *mmc_get_dev(int dev
  }
  #endif
  
 +/* board-specific MMC power initializations. */
 +__weak void board_mmc_power_init(void)
 +{
 +}
 +
  int mmc_start_init(struct mmc *mmc)
  {
        int err;
  
 -      if (mmc_getcd(mmc) == 0) {
 +      /* we pretend there's no card when init is NULL */
 +      if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
                mmc->has_init = 0;
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: no card present\n");
 +#endif
                return NO_CARD_ERR;
        }
  
        if (mmc->has_init)
                return 0;
  
 -      err = mmc->init(mmc);
 +      board_mmc_power_init();
 +
 +      /* made sure it's not NULL earlier */
 +      err = mmc->cfg->ops->init(mmc);
  
        if (err)
                return err;
  
 +      mmc->ddr_mode = 0;
        mmc_set_bus_width(mmc, 1);
        mmc_set_clock(mmc, 1);
  
                err = mmc_send_op_cond(mmc);
  
                if (err && err != IN_PROGRESS) {
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                        printf("Card did not respond to voltage select!\n");
 +#endif
                        return UNUSABLE_ERR;
                }
        }
@@@ -1396,13 -1412,10 +1399,13 @@@ static int mmc_complete_init(struct mm
  int mmc_init(struct mmc *mmc)
  {
        int err = IN_PROGRESS;
 -      unsigned start = get_timer(0);
 +      unsigned start;
  
        if (mmc->has_init)
                return 0;
 +
 +      start = get_timer(0);
 +
        if (!mmc->init_in_progress)
                err = mmc_start_init(mmc);
  
        return err;
  }
  
 -/*
 - * CPU and board-specific MMC initializations.  Aliased function
 - * signals caller to move on
 - */
 -static int __def_mmc_init(bd_t *bis)
 +int mmc_set_dsr(struct mmc *mmc, u16 val)
 +{
 +      mmc->dsr = val;
 +      return 0;
 +}
 +
 +/* CPU-specific MMC initializations */
 +__weak int cpu_mmc_init(bd_t *bis)
 +{
 +      return -1;
 +}
 +
 +/* board-specific MMC initializations. */
 +__weak int board_mmc_init(bd_t *bis)
  {
        return -1;
  }
  
 -int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 -int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
 +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
  
  void print_mmc_devices(char separator)
  {
        list_for_each(entry, &mmc_devices) {
                m = list_entry(entry, struct mmc, link);
  
 -              printf("%s: %d", m->name, m->block_dev.dev);
 +              printf("%s: %d", m->cfg->name, m->block_dev.dev);
  
 -              if (entry->next != &mmc_devices)
 -                      printf("%c ", separator);
 +              if (entry->next != &mmc_devices) {
 +                      printf("%c", separator);
 +                      if (separator != '\n')
 +                              puts (" ");
 +              }
        }
  
        printf("\n");
  }
  
 +#else
 +void print_mmc_devices(char separator) { }
 +#endif
 +
  int get_mmc_num(void)
  {
        return cur_dev_num;
@@@ -1488,9 -1486,7 +1491,9 @@@ int mmc_initialize(bd_t *bis
        if (board_mmc_init(bis) < 0)
                cpu_mmc_init(bis);
  
 +#ifndef CONFIG_SPL_BUILD
        print_mmc_devices(',');
 +#endif
  
        do_preinit();
        return 0;
@@@ -1565,56 -1561,67 +1568,56 @@@ int mmc_boot_partition_size_change(stru
  }
  
  /*
 - * This function shall form and send the commands to open / close the
 - * boot partition specified by user.
 - *
 - * Input Parameters:
 - * ack: 0x0 - No boot acknowledge sent (default)
 - *    0x1 - Boot acknowledge sent during boot operation
 - * part_num: User selects boot data that will be sent to master
 - *    0x0 - Device not boot enabled (default)
 - *    0x1 - Boot partition 1 enabled for boot
 - *    0x2 - Boot partition 2 enabled for boot
 - * access: User selects partitions to access
 - *    0x0 : No access to boot partition (default)
 - *    0x1 : R/W boot partition 1
 - *    0x2 : R/W boot partition 2
 - *    0x3 : R/W Replay Protected Memory Block (RPMB)
 + * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
 + * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
 + * and BOOT_MODE.
   *
   * Returns 0 on success.
   */
 -int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
 +int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
  {
        int err;
 -      struct mmc_cmd cmd;
  
 -      /* Boot ack enable, boot partition enable , boot partition access */
 -      cmd.cmdidx = MMC_CMD_SWITCH;
 -      cmd.resp_type = MMC_RSP_R1b;
 -
 -      cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
 -                      (EXT_CSD_PART_CONF << 16) |
 -                      ((EXT_CSD_BOOT_ACK(ack) |
 -                      EXT_CSD_BOOT_PART_NUM(part_num) |
 -                      EXT_CSD_PARTITION_ACCESS(access)) << 8);
 +      err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
 +                       EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
 +                       EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
 +                       EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
  
 -      err = mmc_send_cmd(mmc, &cmd, NULL);
 -      if (err) {
 -              if (access) {
 -                      debug("mmc boot partition#%d open fail:Error1 = %d\n",
 -                            part_num, err);
 -              } else {
 -                      debug("mmc boot partition#%d close fail:Error = %d\n",
 -                            part_num, err);
 -              }
 +      if (err)
                return err;
 -      }
 +      return 0;
 +}
  
 -      if (access) {
 -              /* 4bit transfer mode at booting time. */
 -              cmd.cmdidx = MMC_CMD_SWITCH;
 -              cmd.resp_type = MMC_RSP_R1b;
 +/*
 + * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
 + * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
 + * PARTITION_ACCESS.
 + *
 + * Returns 0 on success.
 + */
 +int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
 +{
 +      int err;
  
 -              cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
 -                              (EXT_CSD_BOOT_BUS_WIDTH << 16) |
 -                              ((1 << 0) << 8);
 +      err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
 +                       EXT_CSD_BOOT_ACK(ack) |
 +                       EXT_CSD_BOOT_PART_NUM(part_num) |
 +                       EXT_CSD_PARTITION_ACCESS(access));
  
 -              err = mmc_send_cmd(mmc, &cmd, NULL);
 -              if (err) {
 -                      debug("mmc boot partition#%d open fail:Error2 = %d\n",
 -                            part_num, err);
 -                      return err;
 -              }
 -      }
 +      if (err)
 +              return err;
        return 0;
  }
 +
 +/*
 + * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
 + * for enable.  Note that this is a write-once field for non-zero values.
 + *
 + * Returns 0 on success.
 + */
 +int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
 +{
 +      return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
 +                        enable);
 +}
  #endif
diff --combined drivers/mmc/mxsmmc.c
index 2fa4eeef441f16b552e0742571dd6c625cf85cd5,7c59a6f36784c9b9918004ae8fb06116d34b17cd..6f74299adbdad53c885fc50977530e9f02f7fa2f
@@@ -35,7 -35,6 +35,7 @@@ struct mxsmmc_priv 
        int                     (*mmc_is_wp)(int);
        int                     (*mmc_cd)(int);
        struct mxs_dma_desc     *desc;
 +      struct mmc_config       cfg;    /* mmc configuration */
  };
  
  #define       MXSMMC_MAX_TIMEOUT      10000
@@@ -87,7 -86,8 +87,8 @@@ static int mxsmmc_send_cmd_pio(struct m
        return timeout ? 0 : COMM_ERR;
  }
  
- static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
+ static int mxsmmc_send_cmd_dma(struct mmc *mmc, struct mxsmmc_priv *priv,
+                       struct mmc_data *data)
  {
        uint32_t data_count = data->blocksize * data->blocks;
        int dmach;
@@@ -95,6 -95,9 +96,9 @@@
        void *addr;
        unsigned int flags;
        struct bounce_buffer bbstate;
+       unsigned long xfer_rate = (mmc->clock ?: 400000) * mmc->bus_width;
+       unsigned long dma_timeout = data_count * 8 /
+               DIV_ROUND_UP(xfer_rate, 1000);
  
        memset(desc, 0, sizeof(struct mxs_dma_desc));
        desc->address = (dma_addr_t)desc;
  
        dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id;
        mxs_dma_desc_append(dmach, priv->desc);
+       /* set DMA timeout adding 250ms for min timeout according to SD spec. */
+       mxs_dma_set_timeout(dmach, dma_timeout + 250);
        if (mxs_dma_go(dmach)) {
                bounce_buffer_stop(&bbstate);
                return COMM_ERR;
  static int
  mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
  {
 -      struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
 +      struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
        uint32_t reg;
        int timeout;
        uint32_t ctrl0;
+       const uint32_t busy_stat = SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY |
+               SSP_STATUS_CMD_BUSY;
        int ret;
  
        debug("MMC%d: CMD%d\n", mmc->block_dev.dev, cmd->cmdidx);
  
        /* Check bus busy */
        timeout = MXSMMC_MAX_TIMEOUT;
-       while (--timeout) {
-               udelay(1000);
-               reg = readl(&ssp_regs->hw_ssp_status);
-               if (!(reg &
-                       (SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY |
-                       SSP_STATUS_CMD_BUSY))) {
+       while ((reg = readl(&ssp_regs->hw_ssp_status)) & busy_stat) {
+               if (timeout-- <= 0)
                        break;
-               }
+               udelay(1000);
        }
-       if (!timeout) {
+       if (reg & busy_stat && readl(&ssp_regs->hw_ssp_status) & busy_stat) {
                printf("MMC%d: Bus busy timeout!\n", mmc->block_dev.dev);
                return TIMEOUT;
        }
                if (!(reg & SSP_STATUS_CMD_BUSY))
                        break;
        }
-       if (!timeout) {
+       if ((reg & SSP_STATUS_CMD_BUSY) &&
+               (readl(&ssp_regs->hw_ssp_status) & SSP_STATUS_CMD_BUSY)) {
                printf("MMC%d: Command %d busy\n",
                        mmc->block_dev.dev, cmd->cmdidx);
                return TIMEOUT;
        if (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER) {
                ret = mxsmmc_send_cmd_pio(priv, data);
                if (ret) {
-                       printf("MMC%d: Data timeout with command %d "
-                               "(status 0x%08x)!\n",
+                       printf("MMC%d: Data timeout with command %d (status 0x%08x)!\n",
                                mmc->block_dev.dev, cmd->cmdidx, reg);
                        return ret;
                }
        } else {
-               ret = mxsmmc_send_cmd_dma(priv, data);
+               ret = mxsmmc_send_cmd_dma(mmc, priv, data);
                if (ret) {
                        printf("MMC%d: DMA transfer failed\n",
                                mmc->block_dev.dev);
  
  static void mxsmmc_set_ios(struct mmc *mmc)
  {
 -      struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
 +      struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
  
        /* Set the clock speed */
  
  static int mxsmmc_init(struct mmc *mmc)
  {
 -      struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
 +      struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
  
        /* Reset SSP */
        return 0;
  }
  
 +static const struct mmc_ops mxsmmc_ops = {
 +      .send_cmd       = mxsmmc_send_cmd,
 +      .set_ios        = mxsmmc_set_ios,
 +      .init           = mxsmmc_init,
 +};
 +
  int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
  {
--      struct mmc *mmc = NULL;
--      struct mxsmmc_priv *priv = NULL;
++      struct mmc *mmc;
++      struct mxsmmc_priv *priv;
        int ret;
        const unsigned int mxsmmc_clk_id = mxs_ssp_clock_by_bus(id);
  
        if (!mxs_ssp_bus_id_valid(id))
                return -ENODEV;
  
-       priv = malloc(sizeof(struct mxsmmc_priv));
 -      mmc = calloc(sizeof(struct mmc), 1);
 -      if (!mmc)
 -              return -ENOMEM;
 -
+       priv = calloc(sizeof(struct mxsmmc_priv), 1);
 -      if (!priv) {
 -              free(mmc);
 +      if (!priv)
                return -ENOMEM;
 -      }
  
        priv->desc = mxs_dma_desc_alloc();
        if (!priv->desc) {
--              free(priv);
 -              free(mmc);
--              return -ENOMEM;
++              ret = -ENOMEM;
++              goto free_priv;
        }
  
        ret = mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + id);
        if (ret)
--              return ret;
++              goto free_priv;
  
        priv->mmc_is_wp = wp;
        priv->mmc_cd = cd;
        priv->id = id;
        priv->regs = mxs_ssp_regs_by_bus(id);
  
 -      sprintf(mmc->name, "MXS MMC");
 -      mmc->send_cmd = mxsmmc_send_cmd;
 -      mmc->set_ios = mxsmmc_set_ios;
 -      mmc->init = mxsmmc_init;
 -      mmc->getcd = NULL;
 -      mmc->getwp = NULL;
 -      mmc->priv = priv;
 +      priv->cfg.name = "MXS MMC";
 +      priv->cfg.ops = &mxsmmc_ops;
  
 -      mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 +      priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
  
 -      mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
 -                       MMC_MODE_HS_52MHz | MMC_MODE_HS;
 +      priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
 +                       MMC_MODE_HS_52MHz | MMC_MODE_HS |
 +                       MMC_MODE_HC;
  
        /*
         * SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
         * CLOCK_DIVIDE has to be an even value from 2 to 254, and
         * CLOCK_RATE could be any integer from 0 to 255.
         */
 -      mmc->f_min = 400000;
 -      mmc->f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2;
 -      mmc->b_max = 0x20;
 -
 -      mmc_register(mmc);
 +      priv->cfg.f_min = 400000;
 +      priv->cfg.f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2;
 +      priv->cfg.b_max = 0x20;
 +
 +      mmc = mmc_create(&priv->cfg, priv);
 +      if (mmc == NULL) {
-               mxs_dma_desc_free(priv->desc);
-               free(priv);
-               return -ENOMEM;
++              ret = -ENOMEM;
++              goto free_dma;
 +      }
        return 0;
++
++free_dma:
++      mxs_dma_desc_free(priv->desc);
++free_priv:
++      free(priv);
++      return ret;
  }
diff --combined drivers/mmc/omap_hsmmc.c
index c880cedb0addce6761aa67797bf19ed785a93031,20893217df99649104492c6ebbb72aab99bec896..995ec2c0952483e8e0eb948972766e9747c04259
@@@ -24,7 -24,6 +24,7 @@@
  
  #include <config.h>
  #include <common.h>
 +#include <malloc.h>
  #include <mmc.h>
  #include <part.h>
  #include <i2c.h>
  #include <asm/arch/mmc_host_def.h>
  #include <asm/arch/sys_proto.h>
  
 +/* simplify defines to OMAP_HSMMC_USE_GPIO */
 +#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \
 +      (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT))
 +#define OMAP_HSMMC_USE_GPIO
 +#else
 +#undef OMAP_HSMMC_USE_GPIO
 +#endif
 +
  /* common definitions for all OMAPs */
  #define SYSCTL_SRC    (1 << 25)
  #define SYSCTL_SRD    (1 << 26)
  
  struct omap_hsmmc_data {
        struct hsmmc *base_addr;
 +      struct mmc_config cfg;
 +#ifdef OMAP_HSMMC_USE_GPIO
        int cd_gpio;
        int wp_gpio;
 +#endif
  };
  
  /* If we fail after 1 second wait, something is really bad */
  static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
  static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
                        unsigned int siz);
 -static struct mmc hsmmc_dev[3];
 -static struct omap_hsmmc_data hsmmc_dev_data[3];
  
 -#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \
 -      (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT))
 +#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;
  }
 -
 -static int omap_mmc_getcd(struct mmc *mmc)
 -{
 -      int cd_gpio = ((struct omap_hsmmc_data *)mmc->priv)->cd_gpio;
 -      return gpio_get_value(cd_gpio);
 -}
 -
 -static int omap_mmc_getwp(struct mmc *mmc)
 -{
 -      int wp_gpio = ((struct omap_hsmmc_data *)mmc->priv)->wp_gpio;
 -      return gpio_get_value(wp_gpio);
 -}
 -#else
 -static inline int omap_mmc_setup_gpio_in(int gpio, const char *label)
 -{
 -      return -1;
 -}
 -
 -#define omap_mmc_getcd NULL
 -#define omap_mmc_getwp NULL
  #endif
  
  #if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER)
@@@ -125,7 -131,7 +125,7 @@@ static void omap5_pbias_config(struct m
  }
  #endif
  
- static unsigned char mmc_board_init(struct mmc *mmc)
+ static void mmc_board_init(struct mmc *mmc)
  {
  #if defined(CONFIG_OMAP34XX)
        t2_t *t2_base = (t2_t *)T2_BASE;
        pbias_lite = readl(&t2_base->pbias_lite);
        pbias_lite &= ~(PBIASLITEPWRDNZ1 | PBIASLITEPWRDNZ0);
        writel(pbias_lite, &t2_base->pbias_lite);
 -#endif
 -#if defined(CONFIG_TWL4030_POWER)
 -      twl4030_power_mmc_init();
 -      mdelay(100);    /* ramp-up delay from Linux code */
 -#endif
 -#if defined(CONFIG_OMAP34XX)
 +
        writel(pbias_lite | PBIASLITEPWRDNZ1 |
                PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
                &t2_base->pbias_lite);
                &t2_base->devconf1);
  
        /* Change from default of 52MHz to 26MHz if necessary */
 -      if (!(mmc->host_caps & MMC_MODE_HS_52MHz))
 +      if (!(mmc->cfg->host_caps & MMC_MODE_HS_52MHz))
                writel(readl(&t2_base->ctl_prog_io1) & ~CTLPROGIO1SPEEDCTRL,
                        &t2_base->ctl_prog_io1);
  
        if (mmc->block_dev.dev == 0)
                omap5_pbias_config(mmc);
  #endif
-       return 0;
  }
  
  void mmc_init_stream(struct hsmmc *mmc_base)
        writel(MMC_CMD0, &mmc_base->cmd);
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc!\n", __func__);
+               return;
        }
-       writel(CC_MASK, &mmc_base->stat)
-               ;
-       writel(MMC_CMD0, &mmc_base->cmd)
-               ;
+       writel(CC_MASK, &mmc_base->stat);
+       writel(MMC_CMD0, &mmc_base->cmd);
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc2!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc2!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
  }
  
 -static int mmc_init_setup(struct mmc *mmc)
 +
 +static int omap_hsmmc_init_setup(struct mmc *mmc)
  {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int reg_val;
        unsigned int dsor;
        ulong start;
  
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        mmc_board_init(mmc);
  
        writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
                &mmc_base->sysconfig);
        start = get_timer(0);
        while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc2!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
+               printf("%s: timeout %08x waiting for softreset done!\n", __func__,
+                       readl(&mmc_base->sysstatus));
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
        start = get_timer(0);
-       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for softresetall!\n",
-                               __func__);
-                       return TIMEOUT;
-               }
+       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               printf("%s: timeout waiting for softresetall!\n", __func__);
+               return TIMEOUT;
        }
        writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
        writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
                (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for ics!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
  
@@@ -277,64 -295,43 +285,67 @@@ static void mmc_reset_controller_fsm(st
  
        mmc_reg_out(&mmc_base->sysctl, bit, bit);
  
 +      /*
 +       * CMD(DAT) lines reset procedures are slightly different
 +       * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
 +       * According to OMAP3 TRM:
 +       * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
 +       * returns to 0x0.
 +       * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
 +       * procedure steps must be as follows:
 +       * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
 +       *    MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
 +       * 2. Poll the SRC(SRD) bit until it is set to 0x1.
 +       * 3. Wait until the SRC (SRD) bit returns to 0x0
 +       *    (reset procedure is completed).
 +       */
 +#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
 +      defined(CONFIG_AM33XX)
 +      if (!(readl(&mmc_base->sysctl) & bit)) {
 +              start = get_timer(0);
 +              while (!(readl(&mmc_base->sysctl) & bit)) {
 +                      if (get_timer(0) - start > MAX_RETRY_MS)
 +                              return;
 +              }
 +      }
 +#endif
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & bit) != 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for sysctl %x to clear\n",
-                               __func__, bit);
-                       return;
-               }
+               if (get_timer(0) - start > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & bit) != 0) {
+               printf("%s: timedout waiting for sysctl %x to clear\n", __func__, bit);
+               return;
        }
  }
  
 -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 +static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        struct mmc_data *data)
  {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int flags, mmc_stat;
        ulong start;
  
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        start = get_timer(0);
        while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting on cmd inhibit to clear\n",
-                                       __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
+               printf("%s: timeout waiting on cmd inhibit to clear\n", __func__);
+               return TIMEOUT;
        }
        writel(0xFFFFFFFF, &mmc_base->stat);
        start = get_timer(0);
        while (readl(&mmc_base->stat)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for STAT (%x) to clear\n",
-                               __func__, readl(&mmc_base->stat));
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (readl(&mmc_base->stat)) {
+               printf("%s: timeout waiting for stat!\n", __func__);
+               return TIMEOUT;
        }
        /*
         * CMDREG
        }
  
        writel(cmd->cmdarg, &mmc_base->arg);
 +      udelay(20);             /* To fix "No status update" error on eMMC */
        writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
  
        start = get_timer(0);
-       do {
-               mmc_stat = readl(&mmc_base->stat);
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s : timeout: No status update\n", __func__);
-                       return TIMEOUT;
-               }
-       } while (!mmc_stat);
+       while (!(mmc_stat = readl(&mmc_base->stat))) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!mmc_stat) {
+               printf("%s : timeout: No status update\n", __func__);
+               return TIMEOUT;
+       }
  
        if ((mmc_stat & IE_CTO) != 0) {
                mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);
@@@ -446,14 -443,15 +458,15 @@@ static int mmc_read_data(struct hsmmc *
  
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(0) - start > MAX_RETRY_MS) {
-                               printf("%s: timedout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
  
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
@@@ -494,21 -492,22 +507,22 @@@ static int mmc_write_data(struct hsmmc 
        unsigned int count;
  
        /*
 -       * Start Polled Read
 +       * Start Polled Write
         */
        count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
        count /= 4;
  
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(0) - start > MAX_RETRY_MS) {
-                               printf("%s: timedout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
  
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
        return 0;
  }
  
 -static void mmc_set_ios(struct mmc *mmc)
 +static void omap_hsmmc_set_ios(struct mmc *mmc)
  {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int dsor = 0;
        ulong start;
  
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        /* configue bus width */
        switch (mmc->bus_width) {
        case 8:
  
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for ics!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
  }
  
 +#ifdef OMAP_HSMMC_USE_GPIO
 +static int omap_hsmmc_getcd(struct mmc *mmc)
 +{
 +      struct omap_hsmmc_data *priv_data = mmc->priv;
 +      int cd_gpio;
 +
 +      /* if no CD return as 1 */
 +      cd_gpio = priv_data->cd_gpio;
 +      if (cd_gpio < 0)
 +              return 1;
 +
 +      /* NOTE: assumes card detect signal is active-low */
 +      return !gpio_get_value(cd_gpio);
 +}
 +
 +static int omap_hsmmc_getwp(struct mmc *mmc)
 +{
 +      struct omap_hsmmc_data *priv_data = mmc->priv;
 +      int wp_gpio;
 +
 +      /* if no WP return as 0 */
 +      wp_gpio = priv_data->wp_gpio;
 +      if (wp_gpio < 0)
 +              return 0;
 +
 +      /* NOTE: assumes write protect signal is active-high */
 +      return gpio_get_value(wp_gpio);
 +}
 +#endif
 +
 +static const struct mmc_ops omap_hsmmc_ops = {
 +      .send_cmd       = omap_hsmmc_send_cmd,
 +      .set_ios        = omap_hsmmc_set_ios,
 +      .init           = omap_hsmmc_init_setup,
 +#ifdef OMAP_HSMMC_USE_GPIO
 +      .getcd          = omap_hsmmc_getcd,
 +      .getwp          = omap_hsmmc_getwp,
 +#endif
 +};
 +
  int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio)
  {
++      int ret;
        struct mmc *mmc;
        struct omap_hsmmc_data *priv_data;
 -      unsigned long base_addr;
 +      struct mmc_config *cfg;
 +      uint host_caps_val;
 +
-       priv_data = malloc(sizeof(*priv_data));
++      priv_data = calloc(sizeof(*priv_data), 1);
 +      if (priv_data == NULL)
-               return -1;
++              return -ENOMEM;
 +
 +      host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
 +                           MMC_MODE_HC;
  
        switch (dev_index) {
        case 0:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+               base_addr = OMAP_HSMMC1_BASE;
                break;
  #ifdef OMAP_HSMMC2_BASE
        case 1:
 -              base_addr = OMAP_HSMMC2_BASE;
 +              priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
 +#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
 +     defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)) && \
 +              defined(CONFIG_HSMMC2_8BIT)
 +              /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
 +              host_caps_val |= MMC_MODE_8BIT;
 +#endif
                break;
  #endif
  #ifdef OMAP_HSMMC3_BASE
        case 2:
 -              base_addr = OMAP_HSMMC3_BASE;
 +              priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
 +#if (defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)) && defined(CONFIG_HSMMC3_8BIT)
 +              /* Enable 8-bit interface for eMMC on DRA7XX */
 +              host_caps_val |= MMC_MODE_8BIT;
 +#endif
                break;
  #endif
        default:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
-               return 1;
+               printf("Invalid MMC device index: %d\n", dev_index);
 -              return 1;
++              ret = 1;
++              goto out;
        }
 -
 -      mmc = &hsmmc_dev[dev_index];
 -      priv_data = &hsmmc_dev_data[dev_index];
 -      priv_data->base_addr = (void *)base_addr;
 -
 -      sprintf(mmc->name, "OMAP SD/MMC");
 -      mmc->send_cmd = mmc_send_cmd;
 -      mmc->set_ios = mmc_set_ios;
 -      mmc->init = mmc_init_setup;
 -      mmc->priv = priv_data;
 -
 +#ifdef OMAP_HSMMC_USE_GPIO
 +      /* on error gpio values are set to -1, which is what we want */
        priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
 -      if (priv_data->cd_gpio != -1)
 -              mmc->getcd = omap_mmc_getcd;
 -
        priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
 -      if (priv_data->wp_gpio != -1)
 -              mmc->getwp = omap_mmc_getwp;
 +#endif
 +
 +      cfg = &priv_data->cfg;
  
 -      mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 -      mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
 -                              MMC_MODE_HC) & ~host_caps_mask;
 +      cfg->name = "OMAP SD/MMC";
 +      cfg->ops = &omap_hsmmc_ops;
  
 -      mmc->f_min = 400000;
 +      cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 +      cfg->host_caps = host_caps_val & ~host_caps_mask;
 +
 +      cfg->f_min = 400000;
  
        if (f_max != 0)
 -              mmc->f_max = f_max;
 +              cfg->f_max = f_max;
        else {
 -              if (mmc->host_caps & MMC_MODE_HS) {
 -                      if (mmc->host_caps & MMC_MODE_HS_52MHz)
 -                              mmc->f_max = 52000000;
 +              if (cfg->host_caps & MMC_MODE_HS) {
 +                      if (cfg->host_caps & MMC_MODE_HS_52MHz)
 +                              cfg->f_max = 52000000;
                        else
 -                              mmc->f_max = 26000000;
 +                              cfg->f_max = 26000000;
                } else
 -                      mmc->f_max = 20000000;
 +                      cfg->f_max = 20000000;
        }
  
 -      mmc->b_max = 0;
 +      cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
  
  #if defined(CONFIG_OMAP34XX)
        /*
         * Silicon revs 2.1 and older do not support multiblock transfers.
         */
        if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
 -              mmc->b_max = 1;
 +              cfg->b_max = 1;
  #endif
 -
 -      mmc_register(mmc);
 +      mmc = mmc_create(cfg, priv_data);
-       if (mmc == NULL)
-               return -1;
++      if (mmc == NULL) {
++              ret = -ENOMEM;
++              goto out;
++      }
  
        return 0;
++
++out:
++      free(priv_data);
++      return ret;
  }
diff --combined drivers/mtd/Kconfig
index 415ab4eba9dd71a8f6c103a5321a709fed4f28cf,0000000000000000000000000000000000000000..5b56f11e93497103392146fb1306b264628ec9c0
mode 100644,000000..100644
--- /dev/null
@@@ -1,1 -1,0 +1,21 @@@
++menuconfig NOR_FLASH
++      bool "NOR flash support"
++
++if NOR_FLASH
++
++config CONFIG_FLASH_CFI_DRIVER
++      bool "CFI flash driver"
++
++endif
++
++config SYS_NO_FLASH
++      bool
++      default y
++      depends on !NOR_FLASH
++
++config MTD_PARTITIONS
++      bool "Support MTD partition tables"
++      depends on MTD_DEVICE
++      default y
++
 +source "drivers/mtd/nand/Kconfig"
diff --combined drivers/mtd/nand/Kconfig
index c24221499bfb6cd47f272cd5e71839d7296cf4ea,0000000000000000000000000000000000000000..ebbc2d4a5668a768770f9a24ceb0843ce4fa598b
mode 100644,000000..100644
--- /dev/null
@@@ -1,49 -1,0 +1,74 @@@
- menu "NAND Device Support"
++menuconfig NAND
++      bool "NAND Device Support"
++
++if NAND
++
++config SYS_NAND_USE_FLASH_BBT
++      bool "Use a flash based bad block table"
 +
 +config SYS_NAND_SELF_INIT
 +      bool
 +      help
 +        This option, if enabled, provides more flexible and linux-like
 +        NAND initialization process.
 +
 +if !SPL_BUILD
 +
 +config NAND_DENALI
 +      bool "Support Denali NAND controller"
 +      select SYS_NAND_SELF_INIT
 +      help
 +        Enable support for the Denali NAND controller.
 +
 +config SYS_NAND_DENALI_64BIT
 +      bool "Use 64-bit variant of Denali NAND controller"
 +      depends on NAND_DENALI
 +      help
 +        The Denali NAND controller IP has some variations in terms of
 +        the bus interface.  The DMA setup sequence is completely differenct
 +        between 32bit / 64bit AXI bus variants.
 +
 +        If your Denali NAND controller is the 64-bit variant, say Y.
 +        Otherwise (32 bit), say N.
 +
 +config NAND_DENALI_SPARE_AREA_SKIP_BYTES
 +      int "Number of bytes skipped in OOB area"
 +      depends on NAND_DENALI
 +      range 0 63
 +      help
 +        This option specifies the number of bytes to skip from the beginning
 +        of OOB area before last ECC sector data starts.  This is potentially
 +        used to preserve the bad block marker in the OOB area.
 +
 +endif
 +
 +if SPL_BUILD
 +
 +config SPL_NAND_DENALI
 +      bool "Support Denali NAND controller for SPL"
 +      help
 +        This is a small implementation of the Denali NAND controller
 +        for use on SPL.
 +
 +endif
 +
- endmenu
++config NAND_MXC
++      bool "Support Freescale i.MX NAND controller"
++      select SYS_NAND_SELF_INIT if SPL
++      help
++        Enable support for the Freescale NAND controller found on
++        i.MX processors.
++
++config NAND_MXS
++      bool "Support Freescale GPMI NAND controller"
++      select SYS_NAND_SELF_INIT if SPL
++      help
++        Enable support for the Freescale GPMI NAND controller found
++        on i.MX28 and i.MX6 processors.
++
++config NAND_MXS_NO_BBM_SWAP
++      bool "disable bad block mark swapping"
++      depends on NAND_MXS && MX6
++      select SYS_NAND_USE_FLASH_BBT
++
++endif
index 7a064ab1bf945a2e5724ce9a9bf4e6ad403e1c81,bf368f8a08e8bb18b0ecc83530d532ba79eab8b1..4125a4cd1afd4268cb65a6275217f65b37c63bfd
@@@ -12,6 -12,7 +12,7 @@@
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
+ //#define DEBUG
  
  #include <common.h>
  #include <linux/mtd/mtd.h>
  
  #define       MXS_NAND_COMMAND_BUFFER_SIZE            32
  
+ /* BCH timeout in microseconds */
  #define       MXS_NAND_BCH_TIMEOUT                    10000
  
+ static struct bch_regs *bch_regs = (void *)BCH_BASE_ADDRESS;
+ static struct gpmi_regs *gpmi_regs = (void *)GPMI_BASE_ADDRESS;
  struct mxs_nand_info {
        int             cur_chip;
  
        uint32_t                desc_index;
  };
  
+ #ifdef DEBUG
+ #define dump_reg(b, r)        __dump_reg(&b->r, #r)
+ static inline void __dump_reg(void *addr, const char *name)
+ {
+       printf("%16s[%p]=%08x\n", name, addr, readl(addr));
+ }
+ #define dump_bch_reg(n) __dump_reg(&bch_regs->hw_bch_##n, #n)
+ #define dump_gpmi_reg(n) __dump_reg(&gpmi_regs->hw_gpmi_##n, #n)
+ static inline void dump_regs(void)
+ {
+       printf("BCH:\n");
+       dump_bch_reg(ctrl);
+       dump_bch_reg(status0);
+       dump_bch_reg(mode);
+       dump_bch_reg(debug0);
+       dump_bch_reg(dbgkesread);
+       dump_bch_reg(dbgcsferead);
+       dump_bch_reg(dbgsyndegread);
+       dump_bch_reg(dbgahbmread);
+       dump_bch_reg(blockname);
+       dump_bch_reg(version);
+       printf("\nGPMI:\n");
+       dump_gpmi_reg(ctrl0);
+       dump_gpmi_reg(eccctrl);
+       dump_gpmi_reg(ecccount);
+       dump_gpmi_reg(payload);
+       dump_gpmi_reg(auxiliary);
+       dump_gpmi_reg(ctrl1);
+       dump_gpmi_reg(data);
+       dump_gpmi_reg(stat);
+       dump_gpmi_reg(debug);
+       dump_gpmi_reg(version);
+       dump_gpmi_reg(debug2);
+       dump_gpmi_reg(debug3);
+ }
+ static inline int dbg_addr(void *addr)
+ {
+       if (((unsigned long)addr & ~0xfff) == BCH_BASE_ADDRESS)
+               return 1;
+       return 1;
+ }
+ static inline u32 mxs_readl(void *addr,
+                       const char *fn, int ln)
+ {
+       u32 val = readl(addr);
+       static void *last_addr;
+       static u32 last_val;
+       if (!dbg_addr(addr))
+               return val;
+       if (addr != last_addr || last_val != val) {
+               printf("%s@%d: Read %08x from %p\n", fn, ln, val, addr);
+               last_addr = addr;
+               last_val = val;
+       }
+       return val;
+ }
+ static inline void mxs_writel(u32 val, void *addr,
+                       const char *fn, int ln)
+ {
+       if (dbg_addr(addr))
+               printf("%s@%d: Writing %08x to %p...", fn, ln, val, addr);
+       writel(val, addr);
+       if (dbg_addr(addr))
+               printf(" result: %08x\n", readl(addr));
+ }
+ #undef readl
+ #define readl(a) mxs_readl(a, __func__, __LINE__)
+ #undef writel
+ #define writel(v, a) mxs_writel(v, a, __func__, __LINE__)
+ static inline void memdump(const void *addr, size_t len)
+ {
+       const char *buf = addr;
+       int i;
+       for (i = 0; i < len; i++) {
+               if (i % 16 == 0) {
+                       if (i > 0)
+                               printf("\n");
+                       printf("%p:", &buf[i]);
+               }
+               printf(" %02x", buf[i]);
+       }
+       printf("\n");
+ }
+ #else
+ static inline void memdump(void *addr, size_t len)
+ {
+ }
+ static inline void dump_regs(void)
+ {
+ }
+ #endif
  struct nand_ecclayout fake_ecc_layout;
  
  /*
@@@ -128,12 -235,13 +235,13 @@@ static void mxs_nand_return_dma_descs(s
        info->desc_index = 0;
  }
  
- static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
+ static uint32_t mxs_nand_ecc_chunk_cnt(struct mtd_info *mtd)
  {
-       return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+       struct nand_chip *nand = mtd->priv;
+       return mtd->writesize / nand->ecc.size;
  }
  
- static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
+ static inline uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
  {
        return ecc_strength * 13;
  }
@@@ -143,16 -251,32 +251,37 @@@ static uint32_t mxs_nand_aux_status_off
        return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
  }
  
+ static int mxs_nand_gpmi_init(void)
+ {
+       int ret;
+       /* Reset the GPMI block. */
+       ret = mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
+       if (ret)
+               return ret;
+       /*
+        * Choose NAND mode, set IRQ polarity, disable write protection and
+        * select BCH ECC.
+        */
+       clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
+                       GPMI_CTRL1_GPMI_MODE,
+                       GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
+                       GPMI_CTRL1_BCH_MODE);
+       writel(0x500 << 16, &gpmi_regs->hw_gpmi_timing1);
+       return 0;
+ }
  static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
                                                uint32_t page_oob_size)
  {
 -      if (page_data_size == 2048)
 -              return 8;
 +      if (page_data_size == 2048) {
 +              if (page_oob_size == 64)
 +                      return 8;
 +
 +              if (page_oob_size == 112)
 +                      return 14;
 +      }
  
        if (page_data_size == 4096) {
                if (page_oob_size == 128)
  
                if (page_oob_size == 218)
                        return 16;
 +
 +              if (page_oob_size == 224)
 +                      return 16;
        }
  
        return 0;
@@@ -217,14 -338,14 +346,14 @@@ static inline uint32_t mxs_nand_get_mar
        return block_mark_bit_offset;
  }
  
- static uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
+ static inline uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
  {
        uint32_t ecc_strength;
        ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
        return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3;
  }
  
- static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
+ static inline uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
  {
        uint32_t ecc_strength;
        ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
   */
  static int mxs_nand_wait_for_bch_complete(void)
  {
-       struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
        int timeout = MXS_NAND_BCH_TIMEOUT;
        int ret;
  
        ret = mxs_wait_mask_set(&bch_regs->hw_bch_ctrl_reg,
                BCH_CTRL_COMPLETE_IRQ, timeout);
+       if (ret) {
+               debug("%s@%d: %d\n", __func__, __LINE__, ret);
+               mxs_nand_gpmi_init();
+       }
  
        writel(BCH_CTRL_COMPLETE_IRQ, &bch_regs->hw_bch_ctrl_clr);
  
@@@ -325,8 -449,15 +457,15 @@@ static void mxs_nand_cmd_ctrl(struct mt
  
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
-       if (ret)
-               printf("MXS NAND: Error sending command\n");
+       if (ret) {
+               int i;
+               printf("MXS NAND: Error sending command %08lx\n", d->cmd.pio_words[0]);
+               for (i = 0; i < nand_info->cmd_queue_len; i++) {
+                       printf("%02x ", nand_info->cmd_buf[i]);
+               }
+               printf("\n");
+       }
  
        mxs_nand_return_dma_descs(nand_info);
  
@@@ -341,8 -472,6 +480,6 @@@ static int mxs_nand_device_ready(struc
  {
        struct nand_chip *chip = mtd->priv;
        struct mxs_nand_info *nand_info = chip->priv;
-       struct mxs_gpmi_regs *gpmi_regs =
-               (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
        uint32_t tmp;
  
        tmp = readl(&gpmi_regs->hw_gpmi_stat);
@@@ -369,6 -498,7 +506,7 @@@ static void mxs_nand_select_chip(struc
   * swapping the block mark, or swapping it *back* -- but it doesn't matter
   * because the the operation is the same.
   */
+ #ifndef CONFIG_NAND_MXS_NO_BBM_SWAP
  static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
                                        uint8_t *data_buf, uint8_t *oob_buf)
  {
  
        dst = oob_buf[0];
  
+       debug("Swapping byte %02x @ %03x.%d with %02x @ %03x\n",
+               src & 0xff, buf_offset, bit_offset, dst & 0xff, 0);
        oob_buf[0] = src;
  
        data_buf[buf_offset] &= ~(0xff << bit_offset);
        data_buf[buf_offset] |= dst << bit_offset;
        data_buf[buf_offset + 1] |= dst >> (8 - bit_offset);
  }
+ #else
+ static inline void mxs_nand_swap_block_mark(struct mtd_info *mtd,
+                                       uint8_t *data_buf, uint8_t *oob_buf)
+ {
+ }
+ #endif
  
  /*
   * Read data from NAND.
@@@ -422,6 -561,8 +569,8 @@@ static void mxs_nand_read_buf(struct mt
                return;
        }
  
+       memset(buf, 0xee, length);
        /* Compile the DMA descriptor - a descriptor that reads data. */
        d = mxs_nand_get_dma_desc(nand_info);
        d->cmd.data =
                length;
  
        mxs_dma_desc_append(channel, d);
+ #ifndef CONFIG_MX6Q
        /*
         * A DMA descriptor that waits for the command to end and the chip to
         * become ready.
                GPMI_CTRL0_ADDRESS_NAND_DATA;
  
        mxs_dma_desc_append(channel, d);
+ #endif
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA read error\n");
+               printf("%s: DMA read error\n", __func__);
                goto rtn;
        }
  
@@@ -530,7 -671,7 +679,7 @@@ static void mxs_nand_write_buf(struct m
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret)
-               printf("MXS NAND: DMA write error\n");
+               printf("%s: DMA write error\n", __func__);
  
        mxs_nand_return_dma_descs(nand_info);
  }
@@@ -545,6 -686,16 +694,16 @@@ static uint8_t mxs_nand_read_byte(struc
        return buf;
  }
  
+ static void flush_buffers(struct mtd_info *mtd, struct mxs_nand_info *nand_info)
+ {
+       flush_dcache_range((unsigned long)nand_info->data_buf,
+                       (unsigned long)nand_info->data_buf +
+                       mtd->writesize);
+       flush_dcache_range((unsigned long)nand_info->oob_buf,
+                       (unsigned long)nand_info->oob_buf +
+                       mtd->oobsize);
+ }
  /*
   * Read a page from NAND.
   */
@@@ -599,6 -750,8 +758,8 @@@ static int mxs_nand_ecc_read_page(struc
        d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
        d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
  
+       flush_buffers(mtd, nand_info);
        mxs_dma_desc_append(channel, d);
  
        /* Compile the DMA descriptor - disable the BCH block. */
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA read error\n");
+               printf("%s: DMA read error\n", __func__);
                goto rtn;
        }
  
  
        /* Loop over status bytes, accumulating ECC status. */
        status = nand_info->oob_buf + mxs_nand_aux_status_offset();
-       for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) {
+       for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd); i++) {
                if (status[i] == 0x00)
                        continue;
  
@@@ -729,10 -882,12 +890,12 @@@ static int mxs_nand_ecc_write_page(stru
                GPMI_ECCCTRL_ENABLE_ECC |
                GPMI_ECCCTRL_ECC_CMD_ENCODE |
                GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-       d->cmd.pio_words[3] = (mtd->writesize + mtd->oobsize);
+       d->cmd.pio_words[3] = mtd->writesize + mtd->oobsize;
        d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
        d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
  
+       flush_buffers(mtd, nand_info);
        mxs_dma_desc_append(channel, d);
  
        /* Flush caches */
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA write error\n");
+               printf("%s: DMA write error\n", __func__);
                goto rtn;
        }
  
        ret = mxs_nand_wait_for_bch_complete();
        if (ret) {
-               printf("MXS NAND: BCH write timeout\n");
+               printf("%s: BCH write timeout\n", __func__);
                goto rtn;
        }
  
@@@ -959,7 -1114,7 +1122,7 @@@ static int mxs_nand_block_bad(struct mt
  /*
   * Nominally, the purpose of this function is to look for or create the bad
   * block table. In fact, since the we call this function at the very end of
-  * the initialization process started by nand_scan(), and we doesn't have a
+  * the initialization process started by nand_scan(), and we don't have a
   * more formal mechanism, we "hook" this function to continue init process.
   *
   * At this point, the physical NAND Flash chips have been identified and
@@@ -974,14 -1129,25 +1137,25 @@@ static int mxs_nand_scan_bbt(struct mtd
  {
        struct nand_chip *nand = mtd->priv;
        struct mxs_nand_info *nand_info = nand->priv;
-       struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
        uint32_t tmp;
  
        /* Configure BCH and set NFC geometry */
-       mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
+       if (readl(&bch_regs->hw_bch_ctrl_reg) &
+               (BCH_CTRL_SFTRST | BCH_CTRL_CLKGATE))
+               /* When booting from NAND the BCH engine will already
+                * be operational and obviously does not like being reset here.
+                * There will be occasional read errors upon boot when this
+                * reset is done.
+                */
+               mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
+       readl(&bch_regs->hw_bch_ctrl_reg);
+       debug("mtd->writesize=%d\n", mtd->writesize);
+       debug("mtd->oobsize=%d\n", mtd->oobsize);
+       debug("ecc_strength=%d\n", mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize));
  
        /* Configure layout 0 */
-       tmp = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
+       tmp = (mxs_nand_ecc_chunk_cnt(mtd) - 1)
                << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
        tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
        tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
@@@ -1037,7 -1203,7 +1211,7 @@@ int mxs_nand_alloc_buffers(struct mxs_n
        /* DMA buffers */
        buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size);
        if (!buf) {
-               printf("MXS NAND: Error allocating DMA buffers\n");
+               printf("%s: Error allocating DMA buffers\n", __func__);
                return -ENOMEM;
        }
  
   */
  int mxs_nand_init(struct mxs_nand_info *info)
  {
-       struct mxs_gpmi_regs *gpmi_regs =
-               (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
-       struct mxs_bch_regs *bch_regs =
-               (struct mxs_bch_regs *)MXS_BCH_BASE;
-       int i = 0, j;
+       int ret;
+       int i;
  
        info->desc = malloc(sizeof(struct mxs_dma_desc *) *
                                MXS_NAND_DMA_DESCRIPTOR_COUNT);
-       if (!info->desc)
+       if (!info->desc) {
+               printf("MXS NAND: Unable to allocate DMA descriptor table\n");
+               ret = -ENOMEM;
                goto err1;
+       }
+       mxs_dma_init();
  
        /* Allocate the DMA descriptors. */
        for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
                info->desc[i] = mxs_dma_desc_alloc();
-               if (!info->desc[i])
+               if (!info->desc[i]) {
+                       printf("MXS NAND: Unable to allocate DMA descriptors\n");
+                       ret = -ENOMEM;
                        goto err2;
+               }
        }
  
        /* Init the DMA controller. */
-       for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
-               j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
-               if (mxs_dma_init_channel(j))
+       for (i = 0; i < CONFIG_SYS_NAND_MAX_CHIPS; i++) {
+               const int chan = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + i;
+               ret = mxs_dma_init_channel(chan);
+               if (ret) {
+                       printf("Failed to initialize DMA channel %d\n", chan);
                        goto err3;
+               }
        }
  
-       /* Reset the GPMI block. */
-       mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
-       mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
-       /*
-        * Choose NAND mode, set IRQ polarity, disable write protection and
-        * select BCH ECC.
-        */
-       clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
-                       GPMI_CTRL1_GPMI_MODE,
-                       GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
-                       GPMI_CTRL1_BCH_MODE);
+       ret = mxs_nand_gpmi_init();
+       if (ret)
+               goto err3;
  
        return 0;
  
  err3:
-       for (--j; j >= 0; j--)
-               mxs_dma_release(j);
+       for (--i; i >= 0; i--)
+               mxs_dma_release(i + MXS_DMA_CHANNEL_AHB_APBH_GPMI0);
+       i = MXS_NAND_DMA_DESCRIPTOR_COUNT - 1;
  err2:
        free(info->desc);
- err1:
        for (--i; i >= 0; i--)
                mxs_dma_desc_free(info->desc[i]);
-       printf("MXS NAND: Unable to allocate DMA descriptors\n");
-       return -ENOMEM;
+ err1:
+       return ret;
  }
  
  /*!
@@@ -1149,7 -1315,9 +1323,9 @@@ int board_nand_init(struct nand_chip *n
  
        nand->priv = nand_info;
        nand->options |= NAND_NO_SUBPAGE_WRITE;
+ #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+       nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+ #endif
        nand->cmd_ctrl          = mxs_nand_cmd_ctrl;
  
        nand->dev_ready         = mxs_nand_device_ready;
index 63bdf65f82c46949bce9fc975a469d3cda86311a,a2587b6d25c2061c8926784f8bf8347de014adf3..fa8dace7e9dd5b8f6c2fd93586d1a40219ea05b4
@@@ -4,6 -4,7 +4,6 @@@
   *  Overview:
   *   This is the generic MTD driver for NAND flash devices. It should be
   *   capable of working with almost all NAND chips currently available.
 - *   Basic support for AG-AND chips is provided.
   *
   *    Additional technical information is available on
   *    http://www.linux-mtd.infradead.org/doc/nand.html
@@@ -21,6 -22,8 +21,6 @@@
   *    Enable cached programming for 2k page size chips
   *    Check, if mtd->ecctype should be set to MTD_ECC_HW
   *    if we have HW ECC support.
 - *    The AG-AND chips have nice features for speed improvement,
 - *    which are not supported yet. Read / program 4 pages in one go.
   *    BBT table is not serialized, has to be fixed
   *
   * This program is free software; you can redistribute it and/or modify
   *
   */
  
 -#include <common.h>
 -
 -#define ENOTSUPP      524     /* Operation is not supported */
 +#ifndef __UBOOT__
 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
 +#include <linux/module.h>
 +#include <linux/delay.h>
 +#include <linux/errno.h>
 +#include <linux/err.h>
 +#include <linux/sched.h>
 +#include <linux/slab.h>
 +#include <linux/types.h>
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/nand.h>
 +#include <linux/mtd/nand_ecc.h>
 +#include <linux/mtd/nand_bch.h>
 +#include <linux/interrupt.h>
 +#include <linux/bitops.h>
 +#include <linux/leds.h>
 +#include <linux/io.h>
 +#include <linux/mtd/partitions.h>
 +#else
 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 +#include <common.h>
  #include <malloc.h>
  #include <watchdog.h>
  #include <linux/err.h>
  #include <linux/mtd/nand.h>
  #include <linux/mtd/nand_ecc.h>
  #include <linux/mtd/nand_bch.h>
 -
  #ifdef CONFIG_MTD_PARTITIONS
  #include <linux/mtd/partitions.h>
  #endif
 -
  #include <asm/io.h>
  #include <asm/errno.h>
  
@@@ -76,9 -63,6 +76,9 @@@
  #define CONFIG_SYS_NAND_RESET_CNT 200000
  #endif
  
 +static bool is_module_text_address(unsigned long addr) {return 0;}
 +#endif
 +
  /* Define default oob placement schemes for large and small page devices */
  static struct nand_ecclayout nand_oob_8 = {
        .eccbytes = 3,
@@@ -123,16 -107,13 +123,16 @@@ static struct nand_ecclayout nand_oob_1
                 .length = 78} }
  };
  
 -static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
 -                         int new_state);
 +static int nand_get_device(struct mtd_info *mtd, int new_state);
  
  static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops);
  
 -static int nand_wait(struct mtd_info *mtd, struct nand_chip *this);
 +/*
 + * For devices which display every fart in the system on a separate LED. Is
 + * compiled away when LED support is disabled.
 + */
 +DEFINE_LED_TRIGGER(nand_led_trigger);
  
  static int check_offs_len(struct mtd_info *mtd,
                                        loff_t ofs, uint64_t len)
        int ret = 0;
  
        /* Start address must align on block boundary */
 -      if (ofs & ((1 << chip->phys_erase_shift) - 1)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Unaligned address\n", __func__);
 +      if (ofs & ((1ULL << chip->phys_erase_shift) - 1)) {
 +              pr_debug("%s: unaligned address\n", __func__);
                ret = -EINVAL;
        }
  
        /* Length must align on block boundary */
 -      if (len & ((1 << chip->phys_erase_shift) - 1)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Length not block aligned\n",
 -                                      __func__);
 +      if (len & ((1ULL << chip->phys_erase_shift) - 1)) {
 +              pr_debug("%s: length not block aligned\n", __func__);
                ret = -EINVAL;
        }
  
   * nand_release_device - [GENERIC] release chip
   * @mtd: MTD device structure
   *
 - * Deselect, release chip lock and wake up anyone waiting on the device.
 + * Release chip lock and wake up anyone waiting on the device.
   */
  static void nand_release_device(struct mtd_info *mtd)
  {
        struct nand_chip *chip = mtd->priv;
  
 +#ifndef __UBOOT__
 +      /* Release the controller and the chip */
 +      spin_lock(&chip->controller->lock);
 +      chip->controller->active = NULL;
 +      chip->state = FL_READY;
 +      wake_up(&chip->controller->wq);
 +      spin_unlock(&chip->controller->lock);
 +#else
        /* De-select the NAND device */
        chip->select_chip(mtd, -1);
 +#endif
  }
  
  /**
   * nand_read_byte - [DEFAULT] read one byte from the chip
   * @mtd: MTD device structure
   *
 - * Default read function for 8bit buswidth.
 + * Default read function for 8bit buswidth
   */
 +#ifndef __UBOOT__
 +static uint8_t nand_read_byte(struct mtd_info *mtd)
 +#else
  uint8_t nand_read_byte(struct mtd_info *mtd)
 +#endif
  {
        struct nand_chip *chip = mtd->priv;
        return readb(chip->IO_ADDR_R);
  }
  
  /**
 - * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
 + * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
   * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
   * @mtd: MTD device structure
   *
@@@ -243,86 -212,6 +243,86 @@@ static void nand_select_chip(struct mtd
        }
  }
  
 +/**
 + * nand_write_byte - [DEFAULT] write single byte to chip
 + * @mtd: MTD device structure
 + * @byte: value to write
 + *
 + * Default function to write a byte to I/O[7:0]
 + */
 +static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +
 +      chip->write_buf(mtd, &byte, 1);
 +}
 +
 +/**
 + * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16
 + * @mtd: MTD device structure
 + * @byte: value to write
 + *
 + * Default function to write a byte to I/O[7:0] on a 16-bit wide chip.
 + */
 +static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      uint16_t word = byte;
 +
 +      /*
 +       * It's not entirely clear what should happen to I/O[15:8] when writing
 +       * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads:
 +       *
 +       *    When the host supports a 16-bit bus width, only data is
 +       *    transferred at the 16-bit width. All address and command line
 +       *    transfers shall use only the lower 8-bits of the data bus. During
 +       *    command transfers, the host may place any value on the upper
 +       *    8-bits of the data bus. During address transfers, the host shall
 +       *    set the upper 8-bits of the data bus to 00h.
 +       *
 +       * One user of the write_byte callback is nand_onfi_set_features. The
 +       * four parameters are specified to be written to I/O[7:0], but this is
 +       * neither an address nor a command transfer. Let's assume a 0 on the
 +       * upper I/O lines is OK.
 +       */
 +      chip->write_buf(mtd, (uint8_t *)&word, 2);
 +}
 +
 +#if defined(__UBOOT__) && !defined(CONFIG_BLACKFIN)
 +static void iowrite8_rep(void *addr, const uint8_t *buf, int len)
 +{
 +      int i;
 +
 +      for (i = 0; i < len; i++)
 +              writeb(buf[i], addr);
 +}
 +static void ioread8_rep(void *addr, uint8_t *buf, int len)
 +{
 +      int i;
 +
 +      for (i = 0; i < len; i++)
 +              buf[i] = readb(addr);
 +}
 +
 +static void ioread16_rep(void *addr, void *buf, int len)
 +{
 +      int i;
 +      u16 *p = (u16 *) buf;
 +
 +      for (i = 0; i < len; i++)
 +              p[i] = readw(addr);
 +}
 +
 +static void iowrite16_rep(void *addr, void *buf, int len)
 +{
 +      int i;
 +        u16 *p = (u16 *) buf;
 +
 +        for (i = 0; i < len; i++)
 +                writew(p[i], addr);
 +}
 +#endif
 +
  /**
   * nand_write_buf - [DEFAULT] write buffer to chip
   * @mtd: MTD device structure
   *
   * Default write function for 8bit buswidth.
   */
 +#ifndef __UBOOT__
 +static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 +#else
  void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 +#endif
  {
 -      int i;
        struct nand_chip *chip = mtd->priv;
  
 -      for (i = 0; i < len; i++)
 -              writeb(buf[i], chip->IO_ADDR_W);
 +      iowrite8_rep(chip->IO_ADDR_W, buf, len);
  }
  
  /**
   *
   * Default read function for 8bit buswidth.
   */
 +#ifndef __UBOOT__
 +static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 +#else
  void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 +#endif
  {
 -      int i;
        struct nand_chip *chip = mtd->priv;
  
 -      for (i = 0; i < len; i++)
 -              buf[i] = readb(chip->IO_ADDR_R);
 +      ioread8_rep(chip->IO_ADDR_R, buf, len);
  }
  
 +#ifdef __UBOOT__
 +#if defined(CONFIG_MTD_NAND_VERIFY_WRITE)
  /**
   * nand_verify_buf - [DEFAULT] Verify chip data against buffer
   * @mtd: MTD device structure
@@@ -383,14 -266,14 +383,14 @@@ static int nand_verify_buf(struct mtd_i
  }
  
  /**
 - * nand_write_buf16 - [DEFAULT] write buffer to chip
 + * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
   * @mtd: MTD device structure
 - * @buf: data buffer
 - * @len: number of bytes to write
 + * @buf: buffer containing the data to compare
 + * @len: number of bytes to compare
   *
 - * Default write function for 16bit buswidth.
 + * Default verify function for 16bit buswidth.
   */
 -void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 +static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
  {
        int i;
        struct nand_chip *chip = mtd->priv;
        len >>= 1;
  
        for (i = 0; i < len; i++)
 -              writew(p[i], chip->IO_ADDR_W);
 +              if (p[i] != readw(chip->IO_ADDR_R))
 +                      return -EFAULT;
  
 +      return 0;
  }
 +#endif
 +#endif
  
  /**
 - * nand_read_buf16 - [DEFAULT] read chip data into buffer
 + * nand_write_buf16 - [DEFAULT] write buffer to chip
   * @mtd: MTD device structure
 - * @buf: buffer to store date
 - * @len: number of bytes to read
 + * @buf: data buffer
 + * @len: number of bytes to write
   *
 - * Default read function for 16bit buswidth.
 + * Default write function for 16bit buswidth.
   */
 -void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 +#ifndef __UBOOT__
 +static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 +#else
 +void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 +#endif
  {
 -      int i;
        struct nand_chip *chip = mtd->priv;
        u16 *p = (u16 *) buf;
 -      len >>= 1;
  
 -      for (i = 0; i < len; i++)
 -              p[i] = readw(chip->IO_ADDR_R);
 +      iowrite16_rep(chip->IO_ADDR_W, p, len >> 1);
  }
  
  /**
 - * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
 + * nand_read_buf16 - [DEFAULT] read chip data into buffer
   * @mtd: MTD device structure
 - * @buf: buffer containing the data to compare
 - * @len: number of bytes to compare
 + * @buf: buffer to store date
 + * @len: number of bytes to read
   *
 - * Default verify function for 16bit buswidth.
 + * Default read function for 16bit buswidth.
   */
 -static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 +#ifndef __UBOOT__
 +static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 +#else
 +void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 +#endif
  {
 -      int i;
        struct nand_chip *chip = mtd->priv;
        u16 *p = (u16 *) buf;
 -      len >>= 1;
  
 -      for (i = 0; i < len; i++)
 -              if (p[i] != readw(chip->IO_ADDR_R))
 -                      return -EFAULT;
 -
 -      return 0;
 +      ioread16_rep(chip->IO_ADDR_R, p, len >> 1);
  }
  
  /**
@@@ -468,7 -348,7 +468,7 @@@ static int nand_block_bad(struct mtd_in
        if (getchip) {
                chipnr = (int)(ofs >> chip->chip_shift);
  
 -              nand_get_device(chip, mtd, FL_READING);
 +              nand_get_device(mtd, FL_READING);
  
                /* Select the NAND device */
                chip->select_chip(mtd, chipnr);
                i++;
        } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
  
 -      if (getchip)
 +      if (getchip) {
 +              chip->select_chip(mtd, -1);
                nand_release_device(mtd);
 +      }
  
        return res;
  }
  
  /**
 - * nand_default_block_markbad - [DEFAULT] mark a block bad
 + * nand_default_block_markbad - [DEFAULT] mark a block bad via bad block marker
   * @mtd: MTD device structure
   * @ofs: offset from device start
   *
   * This is the default implementation, which can be overridden by a hardware
 - * specific driver. We try operations in the following order, according to our
 - * bbt_options (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH):
 + * specific driver. It provides the details for writing a bad block marker to a
 + * block.
 + */
 +static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      struct mtd_oob_ops ops;
 +      uint8_t buf[2] = { 0, 0 };
 +      int ret = 0, res, i = 0;
 +
 +      ops.datbuf = NULL;
 +      ops.oobbuf = buf;
 +      ops.ooboffs = chip->badblockpos;
 +      if (chip->options & NAND_BUSWIDTH_16) {
 +              ops.ooboffs &= ~0x01;
 +              ops.len = ops.ooblen = 2;
 +      } else {
 +              ops.len = ops.ooblen = 1;
 +      }
 +      ops.mode = MTD_OPS_PLACE_OOB;
 +
 +      /* Write to first/last page(s) if necessary */
 +      if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
 +              ofs += mtd->erasesize - mtd->writesize;
 +      do {
 +              res = nand_do_write_oob(mtd, ofs, &ops);
 +              if (!ret)
 +                      ret = res;
 +
 +              i++;
 +              ofs += mtd->writesize;
 +      } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
 +
 +      return ret;
 +}
 +
 +/**
 + * nand_block_markbad_lowlevel - mark a block bad
 + * @mtd: MTD device structure
 + * @ofs: offset from device start
 + *
 + * This function performs the generic NAND bad block marking steps (i.e., bad
 + * block table(s) and/or marker(s)). We only allow the hardware driver to
 + * specify how to write bad block markers to OOB (chip->block_markbad).
 + *
 + * We try operations in the following order:
   *  (1) erase the affected block, to allow OOB marker to be written cleanly
 - *  (2) update in-memory BBT
 - *  (3) write bad block marker to OOB area of affected block
 - *  (4) update flash-based BBT
 - * Note that we retain the first error encountered in (3) or (4), finish the
 + *  (2) write bad block marker to OOB area of affected block (unless flag
 + *      NAND_BBT_NO_OOB_BBM is present)
 + *  (3) update the BBT
 + * Note that we retain the first error encountered in (2) or (3), finish the
   * procedures, and dump the error in the end.
  */
 -static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 +static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
  {
        struct nand_chip *chip = mtd->priv;
 -      uint8_t buf[2] = { 0, 0 };
 -      int block, res, ret = 0, i = 0;
 -      int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM);
 +      int res, ret = 0;
  
 -      if (write_oob) {
 +      if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
                struct erase_info einfo;
  
                /* Attempt erase before marking OOB */
                memset(&einfo, 0, sizeof(einfo));
                einfo.mtd = mtd;
                einfo.addr = ofs;
 -              einfo.len = 1 << chip->phys_erase_shift;
 +              einfo.len = 1ULL << chip->phys_erase_shift;
                nand_erase_nand(mtd, &einfo, 0);
 -      }
 -
 -      /* Get block number */
 -      block = (int)(ofs >> chip->bbt_erase_shift);
 -      /* Mark block bad in memory-based BBT */
 -      if (chip->bbt)
 -              chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 -
 -      /* Write bad block marker to OOB */
 -      if (write_oob) {
 -              struct mtd_oob_ops ops;
 -              loff_t wr_ofs = ofs;
 -
 -              nand_get_device(chip, mtd, FL_WRITING);
 -
 -              ops.datbuf = NULL;
 -              ops.oobbuf = buf;
 -              ops.ooboffs = chip->badblockpos;
 -              if (chip->options & NAND_BUSWIDTH_16) {
 -                      ops.ooboffs &= ~0x01;
 -                      ops.len = ops.ooblen = 2;
 -              } else {
 -                      ops.len = ops.ooblen = 1;
 -              }
 -              ops.mode = MTD_OPS_PLACE_OOB;
 -
 -              /* Write to first/last page(s) if necessary */
 -              if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
 -                      wr_ofs += mtd->erasesize - mtd->writesize;
 -              do {
 -                      res = nand_do_write_oob(mtd, wr_ofs, &ops);
 -                      if (!ret)
 -                              ret = res;
 -
 -                      i++;
 -                      wr_ofs += mtd->writesize;
 -              } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
  
 +              /* Write bad block marker to OOB */
 +              nand_get_device(mtd, FL_WRITING);
 +              ret = chip->block_markbad(mtd, ofs);
                nand_release_device(mtd);
        }
  
 -      /* Update flash-based bad block table */
 -      if (chip->bbt_options & NAND_BBT_USE_FLASH) {
 -              res = nand_update_bbt(mtd, ofs);
 +      /* Mark block bad in BBT */
 +      if (chip->bbt) {
 +              res = nand_markbad_bbt(mtd, ofs);
                if (!ret)
                        ret = res;
        }
@@@ -634,8 -504,7 +634,8 @@@ static int nand_block_checkbad(struct m
  {
        struct nand_chip *chip = mtd->priv;
  
 -      if (!(chip->options & NAND_BBT_SCANNED)) {
 +      if (!(chip->options & NAND_SKIP_BBTSCAN) &&
 +          !(chip->options & NAND_BBT_SCANNED)) {
                chip->options |= NAND_BBT_SCANNED;
                chip->scan_bbt(mtd);
        }
        return nand_isbad_bbt(mtd, ofs, allowbbt);
  }
  
 +#ifndef __UBOOT__
 +/**
 + * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
 + * @mtd: MTD device structure
 + * @timeo: Timeout
 + *
 + * Helper function for nand_wait_ready used when needing to wait in interrupt
 + * context.
 + */
 +static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      int i;
 +
 +      /* Wait for the device to get ready */
 +      for (i = 0; i < timeo; i++) {
 +              if (chip->dev_ready(mtd))
 +                      break;
 +              touch_softlockup_watchdog();
 +              mdelay(1);
 +      }
 +}
 +#endif
 +
  /* Wait for the ready pin, after a command. The timeout is caught later. */
  void nand_wait_ready(struct mtd_info *mtd)
  {
        struct nand_chip *chip = mtd->priv;
 +#ifndef __UBOOT__
 +      unsigned long timeo = jiffies + msecs_to_jiffies(20);
 +
 +      /* 400ms timeout */
 +      if (in_interrupt() || oops_in_progress)
 +              return panic_nand_wait_ready(mtd, 400);
 +
 +      led_trigger_event(nand_led_trigger, LED_FULL);
 +      /* Wait until command is processed or timeout occurs */
 +      do {
 +              if (chip->dev_ready(mtd))
 +                      break;
 +              touch_softlockup_watchdog();
 +      } while (time_before(jiffies, timeo));
 +      led_trigger_event(nand_led_trigger, LED_OFF);
 +#else
        u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
        u32 time_start;
  
        time_start = get_timer(0);
 -
        /* Wait until command is processed or timeout occurs */
        while (get_timer(time_start) < timeo) {
                if (chip->dev_ready)
                        if (chip->dev_ready(mtd))
                                break;
        }
 +#endif
  }
 +EXPORT_SYMBOL_GPL(nand_wait_ready);
  
  /**
   * nand_command - [DEFAULT] Send command to NAND device
   * @page_addr: the page address for this command, -1 if none
   *
   * Send command to NAND device. This function is used for small page devices
 - * (256/512 Bytes per page).
 + * (512 Bytes per page).
   */
  static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
        /* Serially input address */
        if (column != -1) {
                /* Adjust columns for 16 bit buswidth */
 -              if (chip->options & NAND_BUSWIDTH_16)
 +              if (chip->options & NAND_BUSWIDTH_16 &&
 +                              !nand_opcode_8bits(command))
                        column >>= 1;
                chip->cmd_ctrl(mtd, column, ctrl);
                ctrl &= ~NAND_CTRL_CHANGE;
@@@ -832,7 -659,8 +832,7 @@@ static void nand_command_lp(struct mtd_
        }
  
        /* Command latch cycle */
 -      chip->cmd_ctrl(mtd, command & 0xff,
 -                     NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
 +      chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
  
        if (column != -1 || page_addr != -1) {
                int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
                /* Serially input address */
                if (column != -1) {
                        /* Adjust columns for 16 bit buswidth */
 -                      if (chip->options & NAND_BUSWIDTH_16)
 +                      if (chip->options & NAND_BUSWIDTH_16 &&
 +                                      !nand_opcode_8bits(command))
                                column >>= 1;
                        chip->cmd_ctrl(mtd, column, ctrl);
                        ctrl &= ~NAND_CTRL_CHANGE;
        case NAND_CMD_SEQIN:
        case NAND_CMD_RNDIN:
        case NAND_CMD_STATUS:
 -      case NAND_CMD_DEPLETE1:
 -              return;
 -
 -      case NAND_CMD_STATUS_ERROR:
 -      case NAND_CMD_STATUS_ERROR0:
 -      case NAND_CMD_STATUS_ERROR1:
 -      case NAND_CMD_STATUS_ERROR2:
 -      case NAND_CMD_STATUS_ERROR3:
 -              /* Read error status commands require only a short delay */
 -              udelay(chip->chip_delay);
                return;
  
        case NAND_CMD_RESET:
  }
  
  /**
 - * nand_get_device - [GENERIC] Get chip for selected access
 + * panic_nand_get_device - [GENERIC] Get chip for selected access
   * @chip: the nand chip descriptor
   * @mtd: MTD device structure
   * @new_state: the state which is requested
   *
 + * Used when in panic, no locks are taken.
 + */
 +static void panic_nand_get_device(struct nand_chip *chip,
 +                    struct mtd_info *mtd, int new_state)
 +{
 +      /* Hardware controller shared among independent devices */
 +      chip->controller->active = chip;
 +      chip->state = new_state;
 +}
 +
 +/**
 + * nand_get_device - [GENERIC] Get chip for selected access
 + * @mtd: MTD device structure
 + * @new_state: the state which is requested
 + *
   * Get the device and lock it for exclusive access
   */
  static int
 -nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
 +nand_get_device(struct mtd_info *mtd, int new_state)
  {
 +      struct nand_chip *chip = mtd->priv;
 +#ifndef __UBOOT__
 +      spinlock_t *lock = &chip->controller->lock;
 +      wait_queue_head_t *wq = &chip->controller->wq;
 +      DECLARE_WAITQUEUE(wait, current);
 +retry:
 +      spin_lock(lock);
 +
 +      /* Hardware controller shared among independent devices */
 +      if (!chip->controller->active)
 +              chip->controller->active = chip;
 +
 +      if (chip->controller->active == chip && chip->state == FL_READY) {
 +              chip->state = new_state;
 +              spin_unlock(lock);
 +              return 0;
 +      }
 +      if (new_state == FL_PM_SUSPENDED) {
 +              if (chip->controller->active->state == FL_PM_SUSPENDED) {
 +                      chip->state = FL_PM_SUSPENDED;
 +                      spin_unlock(lock);
 +                      return 0;
 +              }
 +      }
 +      set_current_state(TASK_UNINTERRUPTIBLE);
 +      add_wait_queue(wq, &wait);
 +      spin_unlock(lock);
 +      schedule();
 +      remove_wait_queue(wq, &wait);
 +      goto retry;
 +#else
        chip->state = new_state;
        return 0;
 +#endif
 +}
 +
 +/**
 + * panic_nand_wait - [GENERIC] wait until the command is done
 + * @mtd: MTD device structure
 + * @chip: NAND chip structure
 + * @timeo: timeout
 + *
 + * Wait for command done. This is a helper function for nand_wait used when
 + * we are in interrupt context. May happen when in panic and trying to write
 + * an oops through mtdoops.
 + */
 +static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
 +                          unsigned long timeo)
 +{
 +      int i;
 +      for (i = 0; i < timeo; i++) {
 +              if (chip->dev_ready) {
 +                      if (chip->dev_ready(mtd))
 +                              break;
 +              } else {
 +                      if (chip->read_byte(mtd) & NAND_STATUS_READY)
 +                              break;
 +              }
 +              mdelay(1);
 +      }
  }
  
  /**
   */
  static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
  {
 -      unsigned long   timeo;
 -      int state = chip->state;
 -      u32 time_start;
  
 -      if (state == FL_ERASING)
 -              timeo = (CONFIG_SYS_HZ * 400) / 1000;
 -      else
 -              timeo = (CONFIG_SYS_HZ * 20) / 1000;
 +      int status, state = chip->state;
 +      unsigned long timeo = (state == FL_ERASING ? 400 : 20);
  
 -      if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
 -              chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1);
 -      else
 -              chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
 +      led_trigger_event(nand_led_trigger, LED_FULL);
  
 -      time_start = get_timer(0);
 +      /*
 +       * Apply this short delay always to ensure that we do wait tWB in any
 +       * case on any machine.
 +       */
 +      ndelay(100);
  
 -      while (1) {
 -              if (get_timer(time_start) > timeo) {
 -                      printf("Timeout!");
 -                      return 0x01;
 -              }
 +      chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
  
 +#ifndef __UBOOT__
 +      if (in_interrupt() || oops_in_progress)
 +              panic_nand_wait(mtd, chip, timeo);
 +      else {
 +              timeo = jiffies + msecs_to_jiffies(timeo);
 +              while (time_before(jiffies, timeo)) {
 +                      if (chip->dev_ready) {
 +                              if (chip->dev_ready(mtd))
 +                                      break;
 +                      } else {
 +                              if (chip->read_byte(mtd) & NAND_STATUS_READY)
 +                                      break;
 +                      }
 +                      cond_resched();
 +              }
 +      }
 +#else
 +      u32 timer = (CONFIG_SYS_HZ * timeo) / 1000;
 +      u32 time_start;
 + 
 +      time_start = get_timer(0);
 +      while (get_timer(time_start) < timer) {
                if (chip->dev_ready) {
                        if (chip->dev_ready(mtd))
                                break;
                                break;
                }
        }
 +#endif
  #ifdef PPCHAMELON_NAND_TIMER_HACK
        time_start = get_timer(0);
        while (get_timer(time_start) < 10)
                ;
  #endif /*  PPCHAMELON_NAND_TIMER_HACK */
 +      led_trigger_event(nand_led_trigger, LED_OFF);
 +
 +      status = (int)chip->read_byte(mtd);
 +      /* This can happen if in case of timeout or buggy dev_ready */
 +      WARN_ON(!(status & NAND_STATUS_READY));
 +      return status;
 +}
 +
 +#ifndef __UBOOT__
 +/**
 + * __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
 + * @mtd: mtd info
 + * @ofs: offset to start unlock from
 + * @len: length to unlock
 + * @invert: when = 0, unlock the range of blocks within the lower and
 + *                    upper boundary address
 + *          when = 1, unlock the range of blocks outside the boundaries
 + *                    of the lower and upper boundary address
 + *
 + * Returs unlock status.
 + */
 +static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 +                                      uint64_t len, int invert)
 +{
 +      int ret = 0;
 +      int status, page;
 +      struct nand_chip *chip = mtd->priv;
  
 -      return (int)chip->read_byte(mtd);
 +      /* Submit address of first page to unlock */
 +      page = ofs >> chip->page_shift;
 +      chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask);
 +
 +      /* Submit address of last page to unlock */
 +      page = (ofs + len) >> chip->page_shift;
 +      chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1,
 +                              (page | invert) & chip->pagemask);
 +
 +      /* Call wait ready function */
 +      status = chip->waitfunc(mtd, chip);
 +      /* See if device thinks it succeeded */
 +      if (status & NAND_STATUS_FAIL) {
 +              pr_debug("%s: error status = 0x%08x\n",
 +                                      __func__, status);
 +              ret = -EIO;
 +      }
 +
 +      return ret;
 +}
 +
 +/**
 + * nand_unlock - [REPLACEABLE] unlocks specified locked blocks
 + * @mtd: mtd info
 + * @ofs: offset to start unlock from
 + * @len: length to unlock
 + *
 + * Returns unlock status.
 + */
 +int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 +{
 +      int ret = 0;
 +      int chipnr;
 +      struct nand_chip *chip = mtd->priv;
 +
 +      pr_debug("%s: start = 0x%012llx, len = %llu\n",
 +                      __func__, (unsigned long long)ofs, len);
 +
 +      if (check_offs_len(mtd, ofs, len))
 +              ret = -EINVAL;
 +
 +      /* Align to last block address if size addresses end of the device */
 +      if (ofs + len == mtd->size)
 +              len -= mtd->erasesize;
 +
 +      nand_get_device(mtd, FL_UNLOCKING);
 +
 +      /* Shift to get chip number */
 +      chipnr = ofs >> chip->chip_shift;
 +
 +      chip->select_chip(mtd, chipnr);
 +
 +      /* Check, if it is write protected */
 +      if (nand_check_wp(mtd)) {
 +              pr_debug("%s: device is write protected!\n",
 +                                      __func__);
 +              ret = -EIO;
 +              goto out;
 +      }
 +
 +      ret = __nand_unlock(mtd, ofs, len, 0);
 +
 +out:
 +      chip->select_chip(mtd, -1);
 +      nand_release_device(mtd);
 +
 +      return ret;
  }
 +EXPORT_SYMBOL(nand_unlock);
 +
 +/**
 + * nand_lock - [REPLACEABLE] locks all blocks present in the device
 + * @mtd: mtd info
 + * @ofs: offset to start unlock from
 + * @len: length to unlock
 + *
 + * This feature is not supported in many NAND parts. 'Micron' NAND parts do
 + * have this feature, but it allows only to lock all blocks, not for specified
 + * range for block. Implementing 'lock' feature by making use of 'unlock', for
 + * now.
 + *
 + * Returns lock status.
 + */
 +int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 +{
 +      int ret = 0;
 +      int chipnr, status, page;
 +      struct nand_chip *chip = mtd->priv;
 +
 +      pr_debug("%s: start = 0x%012llx, len = %llu\n",
 +                      __func__, (unsigned long long)ofs, len);
 +
 +      if (check_offs_len(mtd, ofs, len))
 +              ret = -EINVAL;
 +
 +      nand_get_device(mtd, FL_LOCKING);
 +
 +      /* Shift to get chip number */
 +      chipnr = ofs >> chip->chip_shift;
 +
 +      chip->select_chip(mtd, chipnr);
 +
 +      /* Check, if it is write protected */
 +      if (nand_check_wp(mtd)) {
 +              pr_debug("%s: device is write protected!\n",
 +                                      __func__);
 +              status = MTD_ERASE_FAILED;
 +              ret = -EIO;
 +              goto out;
 +      }
 +
 +      /* Submit address of first page to lock */
 +      page = ofs >> chip->page_shift;
 +      chip->cmdfunc(mtd, NAND_CMD_LOCK, -1, page & chip->pagemask);
 +
 +      /* Call wait ready function */
 +      status = chip->waitfunc(mtd, chip);
 +      /* See if device thinks it succeeded */
 +      if (status & NAND_STATUS_FAIL) {
 +              pr_debug("%s: error status = 0x%08x\n",
 +                                      __func__, status);
 +              ret = -EIO;
 +              goto out;
 +      }
 +
 +      ret = __nand_unlock(mtd, ofs, len, 0x1);
 +
 +out:
 +      chip->select_chip(mtd, -1);
 +      nand_release_device(mtd);
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL(nand_lock);
 +#endif
  
  /**
   * nand_read_page_raw - [INTERN] read raw page data without ecc
@@@ -1315,7 -904,6 +1315,7 @@@ static int nand_read_page_swecc(struct 
        uint8_t *ecc_calc = chip->buffers->ecccalc;
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 +      unsigned int max_bitflips = 0;
  
        chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
  
                int stat;
  
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
 -              if (stat < 0)
 +              if (stat < 0) {
                        mtd->ecc_stats.failed++;
 -              else
 +              } else {
                        mtd->ecc_stats.corrected += stat;
 +                      max_bitflips = max_t(unsigned int, max_bitflips, stat);
 +              }
        }
 -      return 0;
 +      return max_bitflips;
  }
  
  /**
 - * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
 + * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function
   * @mtd: mtd info structure
   * @chip: nand chip info structure
   * @data_offs: offset of requested data within the page
   * @readlen: data length
   * @bufpoi: buffer to store read data
 + * @page: page number to read
   */
  static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 -                      uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
 +                      uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
 +                      int page)
  {
        int start_step, end_step, num_steps;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
        int data_col_addr, i, gaps = 0;
        int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
 -      int index = 0;
 +      int index;
 +      unsigned int max_bitflips = 0;
  
        /* Column address within the page aligned to ECC size (256bytes) */
        start_step = data_offs / chip->ecc.size;
        end_step = (data_offs + readlen - 1) / chip->ecc.size;
        num_steps = end_step - start_step + 1;
 +      index = start_step * chip->ecc.bytes;
  
        /* Data size aligned to ECC ecc.size */
        datafrag_len = num_steps * chip->ecc.size;
                 * Send the command to read the particular ECC bytes take care
                 * about buswidth alignment in read_buf.
                 */
 -              index = start_step * chip->ecc.bytes;
 -
                aligned_pos = eccpos[index] & ~(busw - 1);
                aligned_len = eccfrag_len;
                if (eccpos[index] & (busw - 1))
  
                stat = chip->ecc.correct(mtd, p,
                        &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
 -              if (stat < 0)
 +              if (stat < 0) {
                        mtd->ecc_stats.failed++;
 -              else
 +              } else {
                        mtd->ecc_stats.corrected += stat;
 +                      max_bitflips = max_t(unsigned int, max_bitflips, stat);
 +              }
        }
 -      return 0;
 +      return max_bitflips;
  }
  
  /**
@@@ -1456,7 -1038,6 +1456,7 @@@ static int nand_read_page_hwecc(struct 
        uint8_t *ecc_calc = chip->buffers->ecccalc;
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 +      unsigned int max_bitflips = 0;
  
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                chip->ecc.hwctl(mtd, NAND_ECC_READ);
                int stat;
  
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
 -              if (stat < 0)
 +              if (stat < 0) {
                        mtd->ecc_stats.failed++;
 -              else
 +              } else {
                        mtd->ecc_stats.corrected += stat;
 +                      max_bitflips = max_t(unsigned int, max_bitflips, stat);
 +              }
        }
 -      return 0;
 +      return max_bitflips;
  }
  
  /**
@@@ -1509,7 -1088,6 +1509,7 @@@ static int nand_read_page_hwecc_oob_fir
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
        uint8_t *ecc_calc = chip->buffers->ecccalc;
 +      unsigned int max_bitflips = 0;
  
        /* Read the OOB area first */
        chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
  
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
 -              if (stat < 0)
 +              if (stat < 0) {
                        mtd->ecc_stats.failed++;
 -              else
 +              } else {
                        mtd->ecc_stats.corrected += stat;
 +                      max_bitflips = max_t(unsigned int, max_bitflips, stat);
 +              }
        }
 -      return 0;
 +      return max_bitflips;
  }
  
  /**
@@@ -1556,7 -1132,6 +1556,7 @@@ static int nand_read_page_syndrome(stru
        int eccsteps = chip->ecc.steps;
        uint8_t *p = buf;
        uint8_t *oob = chip->oob_poi;
 +      unsigned int max_bitflips = 0;
  
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
                int stat;
                chip->read_buf(mtd, oob, eccbytes);
                stat = chip->ecc.correct(mtd, p, oob, NULL);
  
 -              if (stat < 0)
 +              if (stat < 0) {
                        mtd->ecc_stats.failed++;
 -              else
 +              } else {
                        mtd->ecc_stats.corrected += stat;
 +                      max_bitflips = max_t(unsigned int, max_bitflips, stat);
 +              }
  
                oob += eccbytes;
  
        if (i)
                chip->read_buf(mtd, oob, i);
  
 -      return 0;
 +      return max_bitflips;
  }
  
  /**
@@@ -1644,30 -1217,6 +1644,30 @@@ static uint8_t *nand_transfer_oob(struc
        return NULL;
  }
  
 +/**
 + * nand_setup_read_retry - [INTERN] Set the READ RETRY mode
 + * @mtd: MTD device structure
 + * @retry_mode: the retry mode to use
 + *
 + * Some vendors supply a special command to shift the Vt threshold, to be used
 + * when there are too many bitflips in a page (i.e., ECC error). After setting
 + * a new threshold, the host should retry reading the page.
 + */
 +static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +
 +      pr_debug("setting READ RETRY mode %d\n", retry_mode);
 +
 +      if (retry_mode >= chip->read_retries)
 +              return -EINVAL;
 +
 +      if (!chip->setup_read_retry)
 +              return -EOPNOTSUPP;
 +
 +      return chip->setup_read_retry(mtd, retry_mode);
 +}
 +
  /**
   * nand_do_read_ops - [INTERN] Read data with ECC
   * @mtd: MTD device structure
@@@ -1681,6 -1230,7 +1681,6 @@@ static int nand_do_read_ops(struct mtd_
  {
        int chipnr, page, realpage, col, bytes, aligned, oob_required;
        struct nand_chip *chip = mtd->priv;
 -      struct mtd_ecc_stats stats;
        int ret = 0;
        uint32_t readlen = ops->len;
        uint32_t oobreadlen = ops->ooblen;
                mtd->oobavail : mtd->oobsize;
  
        uint8_t *bufpoi, *oob, *buf;
 -
 -      stats = mtd->ecc_stats;
 +      unsigned int max_bitflips = 0;
 +      int retry_mode = 0;
 +      bool ecc_fail = false;
  
        chipnr = (int)(from >> chip->chip_shift);
        chip->select_chip(mtd, chipnr);
        oob_required = oob ? 1 : 0;
  
        while (1) {
 -              WATCHDOG_RESET();
 +              unsigned int ecc_failures = mtd->ecc_stats.failed;
  
 +              WATCHDOG_RESET();
                bytes = min(mtd->writesize - col, readlen);
                aligned = (bytes == mtd->writesize);
  
                if (realpage != chip->pagebuf || oob) {
                        bufpoi = aligned ? buf : chip->buffers->databuf;
  
 +read_retry:
                        chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
  
 -                      /* Now read the page into the buffer */
 +                      /*
 +                       * Now read the page into the buffer.  Absent an error,
 +                       * the read methods return max bitflips per ecc step.
 +                       */
                        if (unlikely(ops->mode == MTD_OPS_RAW))
                                ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
                                                              oob_required,
                                                              page);
                        else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
 -                          !oob)
 +                               !oob)
                                ret = chip->ecc.read_subpage(mtd, chip,
 -                                                      col, bytes, bufpoi);
 +                                                      col, bytes, bufpoi,
 +                                                      page);
                        else
                                ret = chip->ecc.read_page(mtd, chip, bufpoi,
                                                          oob_required, page);
                                break;
                        }
  
 +                      max_bitflips = max_t(unsigned int, max_bitflips, ret);
 +
                        /* Transfer not aligned data */
                        if (!aligned) {
                                if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
 -                                  !(mtd->ecc_stats.failed - stats.failed) &&
 -                                  (ops->mode != MTD_OPS_RAW))
 +                                  !(mtd->ecc_stats.failed - ecc_failures) &&
 +                                  (ops->mode != MTD_OPS_RAW)) {
                                        chip->pagebuf = realpage;
 -                              else
 +                                      chip->pagebuf_bitflips = ret;
 +                              } else {
                                        /* Invalidate page cache */
                                        chip->pagebuf = -1;
 +                              }
                                memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
  
 -                      buf += bytes;
 -
                        if (unlikely(oob)) {
                                int toread = min(oobreadlen, max_oobsize);
  
                                        oobreadlen -= toread;
                                }
                        }
 +
 +                      if (chip->options & NAND_NEED_READRDY) {
 +                              /* Apply delay or wait for ready/busy pin */
 +                              if (!chip->dev_ready)
 +                                      udelay(chip->chip_delay);
 +                              else
 +                                      nand_wait_ready(mtd);
 +                      }
 +
 +                      if (mtd->ecc_stats.failed - ecc_failures) {
 +                              if (retry_mode + 1 < chip->read_retries) {
 +                                      retry_mode++;
 +                                      ret = nand_setup_read_retry(mtd,
 +                                                      retry_mode);
 +                                      if (ret < 0)
 +                                              break;
 +
 +                                      /* Reset failures; retry */
 +                                      mtd->ecc_stats.failed = ecc_failures;
 +                                      goto read_retry;
 +                              } else {
 +                                      /* No more retry modes; real failure */
 +                                      ecc_fail = true;
 +                              }
 +                      }
 +
 +                      buf += bytes;
                } else {
                        memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
 +                      max_bitflips = max_t(unsigned int, max_bitflips,
 +                                           chip->pagebuf_bitflips);
                }
  
                readlen -= bytes;
  
 +              /* Reset to retry mode 0 */
 +              if (retry_mode) {
 +                      ret = nand_setup_read_retry(mtd, 0);
 +                      if (ret < 0)
 +                              break;
 +                      retry_mode = 0;
 +              }
 +
                if (!readlen)
                        break;
  
                        chip->select_chip(mtd, chipnr);
                }
        }
 +      chip->select_chip(mtd, -1);
  
        ops->retlen = ops->len - (size_t) readlen;
        if (oob)
                ops->oobretlen = ops->ooblen - oobreadlen;
  
 -      if (ret)
 +      if (ret < 0)
                return ret;
  
 -      if (mtd->ecc_stats.failed - stats.failed)
 +      if (ecc_fail)
                return -EBADMSG;
  
 -      return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 +      return max_bitflips;
  }
  
  /**
  static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, uint8_t *buf)
  {
 -      struct nand_chip *chip = mtd->priv;
        struct mtd_oob_ops ops;
        int ret;
  
 -      nand_get_device(chip, mtd, FL_READING);
 +      nand_get_device(mtd, FL_READING);
        ops.len = len;
        ops.datbuf = buf;
        ops.oobbuf = NULL;
@@@ -2021,7 -1525,7 +2021,7 @@@ static int nand_do_read_oob(struct mtd_
        uint8_t *buf = ops->oobbuf;
        int ret = 0;
  
 -      MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08Lx, len = %i\n",
 +      pr_debug("%s: from = 0x%08Lx, len = %i\n",
                        __func__, (unsigned long long)from, readlen);
  
        stats = mtd->ecc_stats;
                len = mtd->oobsize;
  
        if (unlikely(ops->ooboffs >= len)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read "
 -                                      "outside oob\n", __func__);
 +              pr_debug("%s: attempt to start read outside oob\n",
 +                              __func__);
                return -EINVAL;
        }
  
        if (unlikely(from >= mtd->size ||
                     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
                                        (from >> chip->page_shift)) * len)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read beyond end "
 -                                      "of device\n", __func__);
 +              pr_debug("%s: attempt to read beyond end of device\n",
 +                              __func__);
                return -EINVAL;
        }
  
  
        while (1) {
                WATCHDOG_RESET();
 +
                if (ops->mode == MTD_OPS_RAW)
                        ret = chip->ecc.read_oob_raw(mtd, chip, page);
                else
                len = min(len, readlen);
                buf = nand_transfer_oob(chip, buf, ops, len);
  
 +              if (chip->options & NAND_NEED_READRDY) {
 +                      /* Apply delay or wait for ready/busy pin */
 +                      if (!chip->dev_ready)
 +                              udelay(chip->chip_delay);
 +                      else
 +                              nand_wait_ready(mtd);
 +              }
 +
                readlen -= len;
                if (!readlen)
                        break;
                        chip->select_chip(mtd, chipnr);
                }
        }
 +      chip->select_chip(mtd, -1);
  
        ops->oobretlen = ops->ooblen - readlen;
  
  static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
  {
 -      struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
  
        ops->retlen = 0;
  
        /* Do not allow reads past end of device */
        if (ops->datbuf && (from + ops->len) > mtd->size) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read "
 -                              "beyond end of device\n", __func__);
 +              pr_debug("%s: attempt to read beyond end of device\n",
 +                              __func__);
                return -EINVAL;
        }
  
 -      nand_get_device(chip, mtd, FL_READING);
 +      nand_get_device(mtd, FL_READING);
  
        switch (ops->mode) {
        case MTD_OPS_PLACE_OOB:
@@@ -2194,7 -1689,7 +2194,7 @@@ static int nand_write_page_raw_syndrome
                        oob += chip->ecc.prepad;
                }
  
 -              chip->read_buf(mtd, oob, eccbytes);
 +              chip->write_buf(mtd, oob, eccbytes);
                oob += eccbytes;
  
                if (chip->ecc.postpad) {
@@@ -2267,68 -1762,6 +2267,68 @@@ static int nand_write_page_hwecc(struc
        return 0;
  }
  
 +
 +/**
 + * nand_write_subpage_hwecc - [REPLACABLE] hardware ECC based subpage write
 + * @mtd:      mtd info structure
 + * @chip:     nand chip info structure
 + * @offset:   column address of subpage within the page
 + * @data_len: data length
 + * @buf:      data buffer
 + * @oob_required: must write chip->oob_poi to OOB
 + */
 +static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 +                              struct nand_chip *chip, uint32_t offset,
 +                              uint32_t data_len, const uint8_t *buf,
 +                              int oob_required)
 +{
 +      uint8_t *oob_buf  = chip->oob_poi;
 +      uint8_t *ecc_calc = chip->buffers->ecccalc;
 +      int ecc_size      = chip->ecc.size;
 +      int ecc_bytes     = chip->ecc.bytes;
 +      int ecc_steps     = chip->ecc.steps;
 +      uint32_t *eccpos  = chip->ecc.layout->eccpos;
 +      uint32_t start_step = offset / ecc_size;
 +      uint32_t end_step   = (offset + data_len - 1) / ecc_size;
 +      int oob_bytes       = mtd->oobsize / ecc_steps;
 +      int step, i;
 +
 +      for (step = 0; step < ecc_steps; step++) {
 +              /* configure controller for WRITE access */
 +              chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
 +
 +              /* write data (untouched subpages already masked by 0xFF) */
 +              chip->write_buf(mtd, buf, ecc_size);
 +
 +              /* mask ECC of un-touched subpages by padding 0xFF */
 +              if ((step < start_step) || (step > end_step))
 +                      memset(ecc_calc, 0xff, ecc_bytes);
 +              else
 +                      chip->ecc.calculate(mtd, buf, ecc_calc);
 +
 +              /* mask OOB of un-touched subpages by padding 0xFF */
 +              /* if oob_required, preserve OOB metadata of written subpage */
 +              if (!oob_required || (step < start_step) || (step > end_step))
 +                      memset(oob_buf, 0xff, oob_bytes);
 +
 +              buf += ecc_size;
 +              ecc_calc += ecc_bytes;
 +              oob_buf  += oob_bytes;
 +      }
 +
 +      /* copy calculated ECC for whole page to chip->buffer->oob */
 +      /* this include masked-value(0xFF) for unwritten subpages */
 +      ecc_calc = chip->buffers->ecccalc;
 +      for (i = 0; i < chip->ecc.total; i++)
 +              chip->oob_poi[eccpos[i]] = ecc_calc[i];
 +
 +      /* write OOB buffer to NAND device */
 +      chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 +
 +      return 0;
 +}
 +
 +
  /**
   * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
   * @mtd: mtd info structure
@@@ -2381,8 -1814,6 +2381,8 @@@ static int nand_write_page_syndrome(str
   * nand_write_page - [REPLACEABLE] write one page
   * @mtd: MTD device structure
   * @chip: NAND chip descriptor
 + * @offset: address offset within the page
 + * @data_len: length of actual data to be written
   * @buf: the data to write
   * @oob_required: must write chip->oob_poi to OOB
   * @page: page number to write
   * @raw: use _raw version of write_page
   */
  static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 -                         const uint8_t *buf, int oob_required, int page,
 -                         int cached, int raw)
 +              uint32_t offset, int data_len, const uint8_t *buf,
 +              int oob_required, int page, int cached, int raw)
  {
 -      int status;
 +      int status, subpage;
 +
 +      if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
 +              chip->ecc.write_subpage)
 +              subpage = offset || (data_len < mtd->writesize);
 +      else
 +              subpage = 0;
  
        chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
  
        if (unlikely(raw))
 -              status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
 +              status = chip->ecc.write_page_raw(mtd, chip, buf,
 +                                                      oob_required);
 +      else if (subpage)
 +              status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
 +                                                       buf, oob_required);
        else
                status = chip->ecc.write_page(mtd, chip, buf, oob_required);
  
         */
        cached = 0;
  
 -      if (!cached || !(chip->options & NAND_CACHEPRG)) {
 +      if (!cached || !NAND_HAS_CACHEPROG(chip)) {
  
                chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
                status = chip->waitfunc(mtd, chip);
                status = chip->waitfunc(mtd, chip);
        }
  
 -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
 +
 +#ifdef __UBOOT__
 +#if defined(CONFIG_MTD_NAND_VERIFY_WRITE)
        /* Send command to read back the data */
        chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
  
        /* Make sure the next page prog is preceded by a status read */
        chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
  #endif
 +#endif
 +
        return 0;
  }
  
@@@ -2513,8 -1930,6 +2513,8 @@@ static uint8_t *nand_fill_oob(struct mt
        return NULL;
  }
  
- #define NOTALIGNED(x) ((x & (chip->subpagesize - 1)) != 0)
++#define NOTALIGNED(x) (((x) & (chip->subpagesize - 1)) != 0)
 +
  /**
   * nand_do_write_ops - [INTERN] NAND write with ECC
   * @mtd: MTD device structure
@@@ -2536,34 -1951,26 +2536,34 @@@ static int nand_do_write_ops(struct mtd
  
        uint8_t *oob = ops->oobbuf;
        uint8_t *buf = ops->datbuf;
 -      int ret, subpage;
 +      int ret;
        int oob_required = oob ? 1 : 0;
  
        ops->retlen = 0;
        if (!writelen)
                return 0;
  
 -      column = to & (mtd->writesize - 1);
 -      subpage = column || (writelen & (mtd->writesize - 1));
 -
 -      if (subpage && oob)
 +#ifndef __UBOOT__
 +      /* Reject writes, which are not page aligned */
 +      if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
 +#else
 +      /* Reject writes, which are not page aligned */
 +      if (NOTALIGNED(to)) {
 +#endif
 +              pr_notice("%s: attempt to write non page aligned data\n",
 +                         __func__);
                return -EINVAL;
 +      }
 +
 +      column = to & (mtd->writesize - 1);
  
        chipnr = (int)(to >> chip->chip_shift);
        chip->select_chip(mtd, chipnr);
  
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
 -              printk (KERN_NOTICE "nand_do_write_ops: Device is write protected\n");
 -              return -EIO;
 +              ret = -EIO;
 +              goto err_out;
        }
  
        realpage = (int)(to >> chip->page_shift);
                chip->pagebuf = -1;
  
        /* Don't allow multipage oob writes with offset */
 -      if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
 -              return -EINVAL;
 +      if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) {
 +              ret = -EINVAL;
 +              goto err_out;
 +      }
  
        while (1) {
 -              WATCHDOG_RESET();
 -
                int bytes = mtd->writesize;
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
  
 +              WATCHDOG_RESET();
                /* Partial page write? */
 -              if (unlikely(column || writelen < mtd->writesize)) {
 +              if (unlikely(column || writelen < (mtd->writesize - 1))) {
                        cached = 0;
                        bytes = min_t(int, bytes - column, (int) writelen);
                        chip->pagebuf = -1;
                        /* We still need to erase leftover OOB data */
                        memset(chip->oob_poi, 0xff, mtd->oobsize);
                }
 -
 -              ret = chip->write_page(mtd, chip, wbuf, oob_required, page,
 -                                     cached, (ops->mode == MTD_OPS_RAW));
 +              ret = chip->write_page(mtd, chip, column, bytes, wbuf,
 +                                      oob_required, page, cached,
 +                                      (ops->mode == MTD_OPS_RAW));
                if (ret)
                        break;
  
        ops->retlen = ops->len - writelen;
        if (unlikely(oob))
                ops->oobretlen = ops->ooblen;
 +
 +err_out:
 +      chip->select_chip(mtd, -1);
 +      return ret;
 +}
 +
 +/**
 + * panic_nand_write - [MTD Interface] NAND write with ECC
 + * @mtd: MTD device structure
 + * @to: offset to write to
 + * @len: number of bytes to write
 + * @retlen: pointer to variable to store the number of written bytes
 + * @buf: the data to write
 + *
 + * NAND write with ECC. Used when performing writes in interrupt context, this
 + * may for example be called by mtdoops when writing an oops while in panic.
 + */
 +static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 +                          size_t *retlen, const uint8_t *buf)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      struct mtd_oob_ops ops;
 +      int ret;
 +
 +      /* Wait for the device to get ready */
 +      panic_nand_wait(mtd, chip, 400);
 +
 +      /* Grab the device */
 +      panic_nand_get_device(chip, mtd, FL_WRITING);
 +
 +      ops.len = len;
 +      ops.datbuf = (uint8_t *)buf;
 +      ops.oobbuf = NULL;
 +      ops.mode = MTD_OPS_PLACE_OOB;
 +
 +      ret = nand_do_write_ops(mtd, to, &ops);
 +
 +      *retlen = ops.retlen;
        return ret;
  }
  
  static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                          size_t *retlen, const uint8_t *buf)
  {
 -      struct nand_chip *chip = mtd->priv;
        struct mtd_oob_ops ops;
        int ret;
  
 -      nand_get_device(chip, mtd, FL_WRITING);
 +      nand_get_device(mtd, FL_WRITING);
        ops.len = len;
        ops.datbuf = (uint8_t *)buf;
        ops.oobbuf = NULL;
@@@ -2713,7 -2082,7 +2713,7 @@@ static int nand_do_write_oob(struct mtd
        int chipnr, page, status, len;
        struct nand_chip *chip = mtd->priv;
  
 -      MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
 +      pr_debug("%s: to = 0x%08x, len = %i\n",
                         __func__, (unsigned int)to, (int)ops->ooblen);
  
        if (ops->mode == MTD_OPS_AUTO_OOB)
  
        /* Do not allow write past end of page */
        if ((ops->ooboffs + ops->ooblen) > len) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write "
 -                              "past end of page\n", __func__);
 +              pr_debug("%s: attempt to write past end of page\n",
 +                              __func__);
                return -EINVAL;
        }
  
        if (unlikely(ops->ooboffs >= len)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start "
 -                              "write outside oob\n", __func__);
 +              pr_debug("%s: attempt to start write outside oob\n",
 +                              __func__);
                return -EINVAL;
        }
  
                     ops->ooboffs + ops->ooblen >
                        ((mtd->size >> chip->page_shift) -
                         (to >> chip->page_shift)) * len)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
 -                              "end of device\n", __func__);
 +              pr_debug("%s: attempt to write beyond end of device\n",
 +                              __func__);
                return -EINVAL;
        }
  
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
  
        /* Check, if it is write protected */
 -      if (nand_check_wp(mtd))
 +      if (nand_check_wp(mtd)) {
 +              chip->select_chip(mtd, -1);
                return -EROFS;
 +      }
  
        /* Invalidate the page cache, if we write to the cached page */
        if (page == chip->pagebuf)
        else
                status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
  
 +      chip->select_chip(mtd, -1);
 +
        if (status)
                return status;
  
  static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
  {
 -      struct nand_chip *chip = mtd->priv;
        int ret = -ENOTSUPP;
  
        ops->retlen = 0;
  
        /* Do not allow writes past end of device */
        if (ops->datbuf && (to + ops->len) > mtd->size) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
 -                              "end of device\n", __func__);
 +              pr_debug("%s: attempt to write beyond end of device\n",
 +                              __func__);
                return -EINVAL;
        }
  
 -      nand_get_device(chip, mtd, FL_WRITING);
 +      nand_get_device(mtd, FL_WRITING);
  
        switch (ops->mode) {
        case MTD_OPS_PLACE_OOB:
@@@ -2842,6 -2208,24 +2842,6 @@@ static void single_erase_cmd(struct mtd
        chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
  }
  
 -/**
 - * multi_erase_cmd - [GENERIC] AND specific block erase command function
 - * @mtd: MTD device structure
 - * @page: the page address of the block which will be erased
 - *
 - * AND multi block erase command function. Erase 4 consecutive blocks.
 - */
 -static void multi_erase_cmd(struct mtd_info *mtd, int page)
 -{
 -      struct nand_chip *chip = mtd->priv;
 -      /* Send commands to erase a block */
 -      chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
 -      chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
 -      chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++);
 -      chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
 -      chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
 -}
 -
  /**
   * nand_erase - [MTD Interface] erase block(s)
   * @mtd: MTD device structure
@@@ -2854,6 -2238,7 +2854,6 @@@ static int nand_erase(struct mtd_info *
        return nand_erase_nand(mtd, instr, 0);
  }
  
 -#define BBT_PAGE_MASK 0xffffff3f
  /**
   * nand_erase_nand - [INTERN] erase block(s)
   * @mtd: MTD device structure
@@@ -2867,17 -2252,19 +2867,17 @@@ int nand_erase_nand(struct mtd_info *mt
  {
        int page, status, pages_per_block, ret, chipnr;
        struct nand_chip *chip = mtd->priv;
 -      loff_t rewrite_bbt[CONFIG_SYS_NAND_MAX_CHIPS] = {0};
 -      unsigned int bbt_masked_page = 0xffffffff;
        loff_t len;
  
 -      MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
 -                              __func__, (unsigned long long)instr->addr,
 -                              (unsigned long long)instr->len);
 +      pr_debug("%s: start = 0x%012llx, len = %llu\n",
 +                      __func__, (unsigned long long)instr->addr,
 +                      (unsigned long long)instr->len);
  
        if (check_offs_len(mtd, instr->addr, instr->len))
                return -EINVAL;
  
        /* Grab the lock and see if the device is available */
 -      nand_get_device(chip, mtd, FL_ERASING);
 +      nand_get_device(mtd, FL_ERASING);
  
        /* Shift to get first page */
        page = (int)(instr->addr >> chip->page_shift);
  
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
 -                                      __func__);
 +              pr_debug("%s: device is write protected!\n",
 +                              __func__);
                instr->state = MTD_ERASE_FAILED;
                goto erase_exit;
        }
  
 -      /*
 -       * If BBT requires refresh, set the BBT page mask to see if the BBT
 -       * should be rewritten. Otherwise the mask is set to 0xffffffff which
 -       * can not be matched. This is also done when the bbt is actually
 -       * erased to avoid recursive updates.
 -       */
 -      if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
 -              bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
 -
        /* Loop through the pages */
        len = instr->len;
  
  
        while (len) {
                WATCHDOG_RESET();
 +
                /* Check if we have a bad block, we do not erase bad blocks! */
                if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) <<
                                        chip->page_shift, 0, allowbbt)) {
                        pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
 -                                 __func__, page);
 +                                  __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
  
                /* See if block erase succeeded */
                if (status & NAND_STATUS_FAIL) {
 -                      MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: Failed erase, "
 -                                      "page 0x%08x\n", __func__, page);
 +                      pr_debug("%s: failed erase, page 0x%08x\n",
 +                                      __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr =
                                ((loff_t)page << chip->page_shift);
                        goto erase_exit;
                }
  
 -              /*
 -               * If BBT requires refresh, set the BBT rewrite flag to the
 -               * page being erased.
 -               */
 -              if (bbt_masked_page != 0xffffffff &&
 -                  (page & BBT_PAGE_MASK) == bbt_masked_page)
 -                      rewrite_bbt[chipnr] =
 -                              ((loff_t)page << chip->page_shift);
 -
                /* Increment page address and decrement length */
 -              len -= (1 << chip->phys_erase_shift);
 +              len -= (1ULL << chip->phys_erase_shift);
                page += pages_per_block;
  
                /* Check, if we cross a chip boundary */
                        chipnr++;
                        chip->select_chip(mtd, -1);
                        chip->select_chip(mtd, chipnr);
 -
 -                      /*
 -                       * If BBT requires refresh and BBT-PERCHIP, set the BBT
 -                       * page mask to see if this BBT should be rewritten.
 -                       */
 -                      if (bbt_masked_page != 0xffffffff &&
 -                          (chip->bbt_td->options & NAND_BBT_PERCHIP))
 -                              bbt_masked_page = chip->bbt_td->pages[chipnr] &
 -                                      BBT_PAGE_MASK;
                }
        }
        instr->state = MTD_ERASE_DONE;
@@@ -2962,13 -2375,29 +2962,13 @@@ erase_exit
        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
  
        /* Deselect and wake up anyone waiting on the device */
 +      chip->select_chip(mtd, -1);
        nand_release_device(mtd);
  
        /* Do call back function */
        if (!ret)
                mtd_erase_callback(instr);
  
 -      /*
 -       * If BBT requires refresh and erase was successful, rewrite any
 -       * selected bad block tables.
 -       */
 -      if (bbt_masked_page == 0xffffffff || ret)
 -              return ret;
 -
 -      for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
 -              if (!rewrite_bbt[chipnr])
 -                      continue;
 -              /* Update the BBT for chip */
 -              MTDDEBUG(MTD_DEBUG_LEVEL0, "%s: nand_update_bbt "
 -                      "(%d:0x%0llx 0x%0x)\n", __func__, chipnr,
 -                      rewrite_bbt[chipnr], chip->bbt_td->pages[chipnr]);
 -              nand_update_bbt(mtd, rewrite_bbt[chipnr]);
 -      }
 -
        /* Return more or less happy */
        return ret;
  }
   */
  static void nand_sync(struct mtd_info *mtd)
  {
 -      struct nand_chip *chip = mtd->priv;
 -
 -      MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
 +      pr_debug("%s: called\n", __func__);
  
        /* Grab the lock and see if the device is available */
 -      nand_get_device(chip, mtd, FL_SYNCING);
 +      nand_get_device(mtd, FL_SYNCING);
        /* Release it and go back */
        nand_release_device(mtd);
  }
@@@ -3006,6 -2437,7 +3006,6 @@@ static int nand_block_isbad(struct mtd_
   */
  static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
  {
 -      struct nand_chip *chip = mtd->priv;
        int ret;
  
        ret = nand_block_isbad(mtd, ofs);
                return ret;
        }
  
 -      return chip->block_markbad(mtd, ofs);
 +      return nand_block_markbad_lowlevel(mtd, ofs);
  }
  
 - /**
 +/**
   * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
   * @mtd: MTD device structure
   * @chip: nand chip info structure
@@@ -3030,19 -2462,12 +3030,19 @@@ static int nand_onfi_set_features(struc
                        int addr, uint8_t *subfeature_param)
  {
        int status;
 +      int i;
  
 -      if (!chip->onfi_version)
 +#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
 +      if (!chip->onfi_version ||
 +          !(le16_to_cpu(chip->onfi_params.opt_cmd)
 +            & ONFI_OPT_CMD_SET_GET_FEATURES))
                return -EINVAL;
 +#endif
  
        chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
 -      chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
 +      for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
 +              chip->write_byte(mtd, subfeature_param[i]);
 +
        status = chip->waitfunc(mtd, chip);
        if (status & NAND_STATUS_FAIL)
                return -EIO;
  static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
                        int addr, uint8_t *subfeature_param)
  {
 -      if (!chip->onfi_version)
 +      int i;
 +
 +#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
 +      if (!chip->onfi_version ||
 +          !(le16_to_cpu(chip->onfi_params.opt_cmd)
 +            & ONFI_OPT_CMD_SET_GET_FEATURES))
                return -EINVAL;
 +#endif
  
        /* clear the sub feature parameters */
        memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
  
        chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
 -      chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
 +      for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
 +              *subfeature_param++ = chip->read_byte(mtd);
        return 0;
  }
  
 +#ifndef __UBOOT__
 +/**
 + * nand_suspend - [MTD Interface] Suspend the NAND flash
 + * @mtd: MTD device structure
 + */
 +static int nand_suspend(struct mtd_info *mtd)
 +{
 +      return nand_get_device(mtd, FL_PM_SUSPENDED);
 +}
 +
 +/**
 + * nand_resume - [MTD Interface] Resume the NAND flash
 + * @mtd: MTD device structure
 + */
 +static void nand_resume(struct mtd_info *mtd)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +
 +      if (chip->state == FL_PM_SUSPENDED)
 +              nand_release_device(mtd);
 +      else
 +              pr_err("%s called for a chip which is not in suspended state\n",
 +                      __func__);
 +}
 +#endif
 +
  /* Set default functions */
  static void nand_set_defaults(struct nand_chip *chip, int busw)
  {
  
        if (!chip->select_chip)
                chip->select_chip = nand_select_chip;
 -      if (!chip->read_byte)
 +
 +      /* set for ONFI nand */
 +      if (!chip->onfi_set_features)
 +              chip->onfi_set_features = nand_onfi_set_features;
 +      if (!chip->onfi_get_features)
 +              chip->onfi_get_features = nand_onfi_get_features;
 +
 +      /* If called twice, pointers that depend on busw may need to be reset */
 +      if (!chip->read_byte || chip->read_byte == nand_read_byte)
                chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
        if (!chip->read_word)
                chip->read_word = nand_read_word;
                chip->block_bad = nand_block_bad;
        if (!chip->block_markbad)
                chip->block_markbad = nand_default_block_markbad;
 -      if (!chip->write_buf)
 +      if (!chip->write_buf || chip->write_buf == nand_write_buf)
                chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
 -      if (!chip->read_buf)
 +      if (!chip->write_byte || chip->write_byte == nand_write_byte)
 +              chip->write_byte = busw ? nand_write_byte16 : nand_write_byte;
 +      if (!chip->read_buf || chip->read_buf == nand_read_buf)
                chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
 -      if (!chip->verify_buf)
 -              chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
        if (!chip->scan_bbt)
                chip->scan_bbt = nand_default_bbt;
 -      if (!chip->controller)
 +#ifdef __UBOOT__
 +#if defined(CONFIG_MTD_NAND_VERIFY_WRITE)
 +      if (!chip->verify_buf)
 +              chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
 +#endif
 +#endif
 +
 +      if (!chip->controller) {
                chip->controller = &chip->hwcontrol;
 +              spin_lock_init(&chip->controller->lock);
 +              init_waitqueue_head(&chip->controller->wq);
 +      }
 +
  }
  
 -#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
  /* Sanitize ONFI strings so we can safely print them */
 +#ifndef __UBOOT__
 +static void sanitize_string(uint8_t *s, size_t len)
 +#else
  static void sanitize_string(char *s, size_t len)
 +#endif
  {
        ssize_t i;
  
@@@ -3193,106 -2563,6 +3193,106 @@@ static u16 onfi_crc16(u16 crc, u8 cons
        return crc;
  }
  
 +#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
 +/* Parse the Extended Parameter Page. */
 +static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
 +              struct nand_chip *chip, struct nand_onfi_params *p)
 +{
 +      struct onfi_ext_param_page *ep;
 +      struct onfi_ext_section *s;
 +      struct onfi_ext_ecc_info *ecc;
 +      uint8_t *cursor;
 +      int ret = -EINVAL;
 +      int len;
 +      int i;
 +
 +      len = le16_to_cpu(p->ext_param_page_length) * 16;
 +      ep = kmalloc(len, GFP_KERNEL);
 +      if (!ep)
 +              return -ENOMEM;
 +
 +      /* Send our own NAND_CMD_PARAM. */
 +      chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
 +
 +      /* Use the Change Read Column command to skip the ONFI param pages. */
 +      chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
 +                      sizeof(*p) * p->num_of_param_pages , -1);
 +
 +      /* Read out the Extended Parameter Page. */
 +      chip->read_buf(mtd, (uint8_t *)ep, len);
 +      if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2)
 +              != le16_to_cpu(ep->crc))) {
 +              pr_debug("fail in the CRC.\n");
 +              goto ext_out;
 +      }
 +
 +      /*
 +       * Check the signature.
 +       * Do not strictly follow the ONFI spec, maybe changed in future.
 +       */
 +#ifndef __UBOOT__
 +      if (strncmp(ep->sig, "EPPS", 4)) {
 +#else
 +      if (strncmp((char *)ep->sig, "EPPS", 4)) {
 +#endif
 +              pr_debug("The signature is invalid.\n");
 +              goto ext_out;
 +      }
 +
 +      /* find the ECC section. */
 +      cursor = (uint8_t *)(ep + 1);
 +      for (i = 0; i < ONFI_EXT_SECTION_MAX; i++) {
 +              s = ep->sections + i;
 +              if (s->type == ONFI_SECTION_TYPE_2)
 +                      break;
 +              cursor += s->length * 16;
 +      }
 +      if (i == ONFI_EXT_SECTION_MAX) {
 +              pr_debug("We can not find the ECC section.\n");
 +              goto ext_out;
 +      }
 +
 +      /* get the info we want. */
 +      ecc = (struct onfi_ext_ecc_info *)cursor;
 +
 +      if (!ecc->codeword_size) {
 +              pr_debug("Invalid codeword size\n");
 +              goto ext_out;
 +      }
 +
 +      chip->ecc_strength_ds = ecc->ecc_bits;
 +      chip->ecc_step_ds = 1 << ecc->codeword_size;
 +      ret = 0;
 +
 +ext_out:
 +      kfree(ep);
 +      return ret;
 +}
 +
 +static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
 +
 +      return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
 +                      feature);
 +}
 +
 +/*
 + * Configure chip properties from Micron vendor-specific ONFI table
 + */
 +static void nand_onfi_detect_micron(struct nand_chip *chip,
 +              struct nand_onfi_params *p)
 +{
 +      struct nand_onfi_vendor_micron *micron = (void *)p->vendor;
 +
 +      if (le16_to_cpu(p->vendor_revision) < 1)
 +              return;
 +
 +      chip->read_retries = micron->read_retry_options;
 +      chip->setup_read_retry = nand_setup_read_retry_micron;
 +}
 +
  /*
   * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
   */
@@@ -3300,7 -2570,7 +3300,7 @@@ static int nand_flash_detect_onfi(struc
                                        int *busw)
  {
        struct nand_onfi_params *p = &chip->onfi_params;
 -      int i;
 +      int i, j;
        int val;
  
        /* Try ONFI for unknown chip or LP */
  
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
 -              chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
 +              for (j = 0; j < sizeof(*p); j++)
 +                      ((uint8_t *)p)[j] = chip->read_byte(mtd);
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
 -                      pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
  
 -      if (i == 3)
 +      if (i == 3) {
 +              pr_err("Could not find valid ONFI parameter page; aborting\n");
                return 0;
 +      }
  
        /* Check version */
        val = le16_to_cpu(p->revision);
                chip->onfi_version = 20;
        else if (val & (1 << 1))
                chip->onfi_version = 10;
 -      else
 -              chip->onfi_version = 0;
  
        if (!chip->onfi_version) {
 -              pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
 +              pr_info("unsupported ONFI version: %d\n", val);
                return 0;
        }
  
        sanitize_string(p->model, sizeof(p->model));
        if (!mtd->name)
                mtd->name = p->model;
 +
        mtd->writesize = le32_to_cpu(p->byte_per_page);
 -      mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
 +
 +      /*
 +       * pages_per_block and blocks_per_lun may not be a power-of-2 size
 +       * (don't ask me who thought of this...). MTD assumes that these
 +       * dimensions will be power-of-2, so just truncate the remaining area.
 +       */
 +      mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
 +      mtd->erasesize *= mtd->writesize;
 +
        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
 -      chip->chipsize = le32_to_cpu(p->blocks_per_lun);
 +
 +      /* See erasesize comment */
 +      chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 -      *busw = 0;
 -      if (le16_to_cpu(p->features) & 1)
 +      chip->bits_per_cell = p->bits_per_cell;
 +
 +      if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
                *busw = NAND_BUSWIDTH_16;
 +      else
 +              *busw = 0;
 +
 +      if (p->ecc_bits != 0xff) {
 +              chip->ecc_strength_ds = p->ecc_bits;
 +              chip->ecc_step_ds = 512;
 +      } else if (chip->onfi_version >= 21 &&
 +              (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
 +
 +              /*
 +               * The nand_flash_detect_ext_param_page() uses the
 +               * Change Read Column command which maybe not supported
 +               * by the chip->cmdfunc. So try to update the chip->cmdfunc
 +               * now. We do not replace user supplied command function.
 +               */
 +              if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
 +                      chip->cmdfunc = nand_command_lp;
 +
 +              /* The Extended Parameter Page is supported since ONFI 2.1. */
 +              if (nand_flash_detect_ext_param_page(mtd, chip, p))
 +                      pr_warn("Failed to detect ONFI extended param page\n");
 +      } else {
 +              pr_warn("Could not retrieve ONFI ECC requirements\n");
 +      }
 +
 +      if (p->jedec_id == NAND_MFR_MICRON)
 +              nand_onfi_detect_micron(chip, p);
  
 -      pr_info("ONFI flash detected\n");
        return 1;
  }
  #else
 -static inline int nand_flash_detect_onfi(struct mtd_info *mtd,
 -                                      struct nand_chip *chip,
 +static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                                        int *busw)
  {
        return 0;
  }
  #endif
  
 +/*
 + * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
 + */
 +static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip,
 +                                      int *busw)
 +{
 +      struct nand_jedec_params *p = &chip->jedec_params;
 +      struct jedec_ecc_info *ecc;
 +      int val;
 +      int i, j;
 +
 +      /* Try JEDEC for unknown chip or LP */
 +      chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
 +      if (chip->read_byte(mtd) != 'J' || chip->read_byte(mtd) != 'E' ||
 +              chip->read_byte(mtd) != 'D' || chip->read_byte(mtd) != 'E' ||
 +              chip->read_byte(mtd) != 'C')
 +              return 0;
 +
 +      chip->cmdfunc(mtd, NAND_CMD_PARAM, 0x40, -1);
 +      for (i = 0; i < 3; i++) {
 +              for (j = 0; j < sizeof(*p); j++)
 +                      ((uint8_t *)p)[j] = chip->read_byte(mtd);
 +
 +              if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
 +                              le16_to_cpu(p->crc))
 +                      break;
 +      }
 +
 +      if (i == 3) {
 +              pr_err("Could not find valid JEDEC parameter page; aborting\n");
 +              return 0;
 +      }
 +
 +      /* Check version */
 +      val = le16_to_cpu(p->revision);
 +      if (val & (1 << 2))
 +              chip->jedec_version = 10;
 +      else if (val & (1 << 1))
 +              chip->jedec_version = 1; /* vendor specific version */
 +
 +      if (!chip->jedec_version) {
 +              pr_info("unsupported JEDEC version: %d\n", val);
 +              return 0;
 +      }
 +
 +      sanitize_string(p->manufacturer, sizeof(p->manufacturer));
 +      sanitize_string(p->model, sizeof(p->model));
 +      if (!mtd->name)
 +              mtd->name = p->model;
 +
 +      mtd->writesize = le32_to_cpu(p->byte_per_page);
 +
 +      /* Please reference to the comment for nand_flash_detect_onfi. */
 +      mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
 +      mtd->erasesize *= mtd->writesize;
 +
 +      mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
 +
 +      /* Please reference to the comment for nand_flash_detect_onfi. */
 +      chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
 +      chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 +      chip->bits_per_cell = p->bits_per_cell;
 +
 +      if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
 +              *busw = NAND_BUSWIDTH_16;
 +      else
 +              *busw = 0;
 +
 +      /* ECC info */
 +      ecc = &p->ecc_info[0];
 +
 +      if (ecc->codeword_size >= 9) {
 +              chip->ecc_strength_ds = ecc->ecc_bits;
 +              chip->ecc_step_ds = 1 << ecc->codeword_size;
 +      } else {
 +              pr_warn("Invalid codeword size\n");
 +      }
 +
 +      return 1;
 +}
 +
  /*
   * nand_id_has_period - Check if an ID string has a given wraparound period
   * @id_data: the ID string
   *
   * Check if an ID string is repeated within a given sequence of bytes at
   * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
 - * period of 2). This is a helper function for nand_id_len(). Returns non-zero
 + * period of 3). This is a helper function for nand_id_len(). Returns non-zero
   * if the repetition has a period of @period; otherwise, returns zero.
   */
  static int nand_id_has_period(u8 *id_data, int arrlen, int period)
@@@ -3544,16 -2696,6 +3544,16 @@@ static int nand_id_len(u8 *id_data, in
        return arrlen;
  }
  
 +/* Extract the bits of per cell from the 3rd byte of the extended ID */
 +static int nand_get_bits_per_cell(u8 cellinfo)
 +{
 +      int bits;
 +
 +      bits = cellinfo & NAND_CI_CELLTYPE_MSK;
 +      bits >>= NAND_CI_CELLTYPE_SHIFT;
 +      return bits + 1;
 +}
 +
  /*
   * Many new NAND share similar device ID codes, which represent the size of the
   * chip. The rest of the parameters must be decoded according to generic or
@@@ -3564,7 -2706,7 +3564,7 @@@ static void nand_decode_ext_id(struct m
  {
        int extid, id_len;
        /* The 3rd id byte holds MLC / multichip data */
 -      chip->cellinfo = id_data[2];
 +      chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
        /* The 4th id byte is the important one */
        extid = id_data[3];
  
         * ID to decide what to do.
         */
        if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
 -                      (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
 -                      id_data[5] != 0x00) {
 +                      !nand_is_slc(chip) && id_data[5] != 0x00) {
                /* Calc pagesize */
                mtd->writesize = 2048 << (extid & 0x03);
                extid >>= 2;
                        mtd->oobsize = 512;
                        break;
                case 6:
 -              default: /* Other cases are "reserved" (unknown) */
                        mtd->oobsize = 640;
                        break;
 +              case 7:
 +              default: /* Other cases are "reserved" (unknown) */
 +                      mtd->oobsize = 1024;
 +                      break;
                }
                extid >>= 2;
                /* Calc blocksize */
                        (((extid >> 1) & 0x04) | (extid & 0x03));
                *busw = 0;
        } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
 -                      (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
 +                      !nand_is_slc(chip)) {
                unsigned int tmp;
  
                /* Calc pagesize */
                extid >>= 2;
                /* Get buswidth information */
                *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
 +
 +              /*
 +               * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
 +               * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
 +               * follows:
 +               * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm,
 +               *                         110b -> 24nm
 +               * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
 +               */
 +              if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
 +                              nand_is_slc(chip) &&
 +                              (id_data[5] & 0x7) == 0x6 /* 24nm */ &&
 +                              !(id_data[4] & 0x80) /* !BENAND */) {
 +                      mtd->oobsize = 32 * mtd->writesize >> 9;
 +              }
 +
        }
  }
  
 - /*
 +/*
   * Old devices have chip data hardcoded in the device ID table. nand_decode_id
   * decodes a matching ID table entry and assigns the MTD size parameters for
   * the chip.
   */
  static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
 -                              const struct nand_flash_dev *type, u8 id_data[8],
 +                              struct nand_flash_dev *type, u8 id_data[8],
                                int *busw)
  {
        int maf_id = id_data[0];
        mtd->oobsize = mtd->writesize / 32;
        *busw = type->options & NAND_BUSWIDTH_16;
  
 +      /* All legacy ID NAND are small-page, SLC */
 +      chip->bits_per_cell = 1;
 +
        /*
         * Check for Spansion/AMD ID + repeating 5th, 6th byte since
         * some Spansion chips have erasesize that conflicts with size
        }
  }
  
 - /*
 +/*
   * Set the bad block marker/indicator (BBM/BBI) patterns according to some
   * heuristic patterns using various detected parameters (e.g., manufacturer,
   * page size, cell-type information).
@@@ -3742,11 -2863,11 +3742,11 @@@ static void nand_decode_bbm_options(str
         * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
         * AMD/Spansion, and Macronix.  All others scan only the first page.
         */
 -      if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
 +      if (!nand_is_slc(chip) &&
                        (maf_id == NAND_MFR_SAMSUNG ||
                         maf_id == NAND_MFR_HYNIX))
                chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
 -      else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
 +      else if ((nand_is_slc(chip) &&
                                (maf_id == NAND_MFR_SAMSUNG ||
                                 maf_id == NAND_MFR_HYNIX ||
                                 maf_id == NAND_MFR_TOSHIBA ||
                chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
  }
  
 +static inline bool is_full_id_nand(struct nand_flash_dev *type)
 +{
 +      return type->id_len;
 +}
 +
 +static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
 +                 struct nand_flash_dev *type, u8 *id_data, int *busw)
 +{
 +#ifndef __UBOOT__
 +      if (!strncmp(type->id, id_data, type->id_len)) {
 +#else
 +      if (!strncmp((char *)type->id, (char *)id_data, type->id_len)) {
 +#endif
 +              mtd->writesize = type->pagesize;
 +              mtd->erasesize = type->erasesize;
 +              mtd->oobsize = type->oobsize;
 +
 +              chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
 +              chip->chipsize = (uint64_t)type->chipsize << 20;
 +              chip->options |= type->options;
 +              chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
 +              chip->ecc_step_ds = NAND_ECC_STEP(type);
 +
 +              *busw = type->options & NAND_BUSWIDTH_16;
 +
 +              if (!mtd->name)
 +                      mtd->name = type->name;
 +
 +              return true;
 +      }
 +      return false;
 +}
 +
  /*
   * Get the flash and manufacturer id and lookup if the type is supported.
   */
 -static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 +static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
 -                                                int busw,
                                                  int *maf_id, int *dev_id,
 -                                                const struct nand_flash_dev *type)
 +                                                struct nand_flash_dev *type)
  {
 -      const char *name;
 +      int busw;
        int i, maf_idx;
        u8 id_data[8];
  
                id_data[i] = chip->read_byte(mtd);
  
        if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
 -              pr_info("%s: second ID read did not match "
 -                      "%02x,%02x against %02x,%02x\n", __func__,
 +              pr_info("second ID read did not match %02x,%02x against %02x,%02x\n",
                        *maf_id, *dev_id, id_data[0], id_data[1]);
                return ERR_PTR(-ENODEV);
        }
        if (!type)
                type = nand_flash_ids;
  
 -      for (; type->name != NULL; type++)
 -              if (*dev_id == type->id)
 -                      break;
 +      for (; type->name != NULL; type++) {
 +              if (is_full_id_nand(type)) {
 +                      if (find_full_id_nand(mtd, chip, type, id_data, &busw))
 +                              goto ident_done;
 +              } else if (*dev_id == type->dev_id) {
 +                              break;
 +              }
 +      }
  
        chip->onfi_version = 0;
        if (!type->name || !type->pagesize) {
                /* Check is chip is ONFI compliant */
                if (nand_flash_detect_onfi(mtd, chip, &busw))
                        goto ident_done;
 +
 +              /* Check if the chip is JEDEC compliant */
 +              if (nand_flash_detect_jedec(mtd, chip, &busw))
 +                      goto ident_done;
        }
  
        if (!type->name)
        } else {
                nand_decode_id(mtd, chip, type, id_data, &busw);
        }
 -      /* Get chip options, preserve non chip based options */
 +      /* Get chip options */
        chip->options |= type->options;
  
        /*
@@@ -3894,19 -2975,15 +3894,19 @@@ ident_done
                        break;
        }
  
 -      /*
 -       * Check, if buswidth is correct. Hardware drivers should set
 -       * chip correct!
 -       */
 -      if (busw != (chip->options & NAND_BUSWIDTH_16)) {
 -              pr_info("NAND device: Manufacturer ID:"
 -                      " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
 -                      *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
 -              pr_warn("NAND bus width %d instead %d bit\n",
 +      if (chip->options & NAND_BUSWIDTH_AUTO) {
 +              WARN_ON(chip->options & NAND_BUSWIDTH_16);
 +              chip->options |= busw;
 +              nand_set_defaults(chip, busw);
 +      } else if (busw != (chip->options & NAND_BUSWIDTH_16)) {
 +              /*
 +               * Check, if buswidth is correct. Hardware drivers should set
 +               * chip correct!
 +               */
 +              pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
 +                      *maf_id, *dev_id);
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, mtd->name);
 +              pr_warn("bus width %d instead %d bit\n",
                           (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
                           busw ? 16 : 8);
                return ERR_PTR(-EINVAL);
        }
  
        chip->badblockbits = 8;
 -
 -      /* Check for AND chips with 4 page planes */
 -      if (chip->options & NAND_4PAGE_ARRAY)
 -              chip->erase_cmd = multi_erase_cmd;
 -      else
 -              chip->erase_cmd = single_erase_cmd;
 +      chip->erase_cmd = single_erase_cmd;
  
        /* Do not replace user supplied command function! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
  
 -      name = type->name;
 +      pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n",
 +              *maf_id, *dev_id);
 +
  #ifdef CONFIG_SYS_NAND_ONFI_DETECTION
        if (chip->onfi_version)
 -              name = chip->onfi_params.model;
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +                              chip->onfi_params.model);
 +      else if (chip->jedec_version)
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +                              chip->jedec_params.model);
 +      else
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +                              type->name);
 +#else
 +      if (chip->jedec_version)
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +                              chip->jedec_params.model);
 +      else
 +              pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +                              type->name);
 +
 +      pr_info("%s %s\n", nand_manuf_ids[maf_idx].name,
 +              type->name);
  #endif
 -      pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
 -              " page size: %d, OOB size: %d\n",
 -              *maf_id, *dev_id, nand_manuf_ids[maf_idx].name,
 -              name,
 -              mtd->writesize, mtd->oobsize);
  
 +      pr_info("%dMiB, %s, page size: %d, OOB size: %d\n",
 +              (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
 +              mtd->writesize, mtd->oobsize);
        return type;
  }
  
   * The mtd->owner field must be set to the module of the caller.
   */
  int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 -                  const struct nand_flash_dev *table)
 +                  struct nand_flash_dev *table)
  {
 -      int i, busw, nand_maf_id, nand_dev_id;
 +      int i, nand_maf_id, nand_dev_id;
        struct nand_chip *chip = mtd->priv;
 -      const struct nand_flash_dev *type;
 +      struct nand_flash_dev *type;
  
 -      /* Get buswidth to select the correct functions */
 -      busw = chip->options & NAND_BUSWIDTH_16;
        /* Set the default functions */
 -      nand_set_defaults(chip, busw);
 +      nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16);
  
        /* Read the flash type */
 -      type = nand_get_flash_type(mtd, chip, busw,
 -                              &nand_maf_id, &nand_dev_id, table);
 +      type = nand_get_flash_type(mtd, chip, &nand_maf_id,
 +                                 &nand_dev_id, table);
  
        if (IS_ERR(type)) {
 -#ifndef CONFIG_SYS_NAND_QUIET_TEST
 -              pr_warn("No NAND device found\n");
 -#endif
 +              if (!(chip->options & NAND_SCAN_SILENT_NODEV))
 +                      pr_warn("No NAND device found\n");
                chip->select_chip(mtd, -1);
                return PTR_ERR(type);
        }
  
 +      chip->select_chip(mtd, -1);
 +
        /* Check for a chip array */
        for (i = 1; i < maxchips; i++) {
                chip->select_chip(mtd, i);
                chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
                /* Read manufacturer and device IDs */
                if (nand_maf_id != chip->read_byte(mtd) ||
 -                  nand_dev_id != chip->read_byte(mtd))
 +                  nand_dev_id != chip->read_byte(mtd)) {
 +                      chip->select_chip(mtd, -1);
                        break;
 +              }
 +              chip->select_chip(mtd, -1);
        }
 +
  #ifdef DEBUG
        if (i > 1)
 -              pr_info("%d NAND chips detected\n", i);
 +              pr_info("%d chips detected\n", i);
  #endif
  
        /* Store the number of chips and calc total size for mtd */
  
        return 0;
  }
 +EXPORT_SYMBOL(nand_scan_ident);
  
  
  /**
@@@ -4042,31 -3103,16 +4042,31 @@@ int nand_scan_tail(struct mtd_info *mtd
  {
        int i;
        struct nand_chip *chip = mtd->priv;
 +      struct nand_ecc_ctrl *ecc = &chip->ecc;
 +      struct nand_buffers *nbuf;
  
        /* New bad blocks should be marked in OOB, flash-based BBT, or both */
        BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
                        !(chip->bbt_options & NAND_BBT_USE_FLASH));
  
 -      if (!(chip->options & NAND_OWN_BUFFERS))
 -              chip->buffers = memalign(ARCH_DMA_MINALIGN,
 -                                       sizeof(*chip->buffers));
 -      if (!chip->buffers)
 -              return chip->options & NAND_OWN_BUFFERS ? -EINVAL : -ENOMEM;
 +      if (!(chip->options & NAND_OWN_BUFFERS)) {
 +#ifndef __UBOOT__
 +              nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
 +                              + mtd->oobsize * 3, GFP_KERNEL);
 +              if (!nbuf)
 +                      return -ENOMEM;
 +              nbuf->ecccalc = (uint8_t *)(nbuf + 1);
 +              nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
 +              nbuf->databuf = nbuf->ecccode + mtd->oobsize;
 +#else
 +              nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
 +#endif
 +
 +              chip->buffers = nbuf;
 +      } else {
 +              if (!chip->buffers)
 +                      return -ENOMEM;
 +      }
  
        /* Set the internal oob buffer location, just after the page data */
        chip->oob_poi = chip->buffers->databuf + mtd->writesize;
        /*
         * If no default placement scheme is given, select an appropriate one.
         */
 -      if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
 +      if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
                switch (mtd->oobsize) {
                case 8:
 -                      chip->ecc.layout = &nand_oob_8;
 +                      ecc->layout = &nand_oob_8;
                        break;
                case 16:
 -                      chip->ecc.layout = &nand_oob_16;
 +                      ecc->layout = &nand_oob_16;
                        break;
                case 64:
 -                      chip->ecc.layout = &nand_oob_64;
 +                      ecc->layout = &nand_oob_64;
                        break;
                case 128:
 -                      chip->ecc.layout = &nand_oob_128;
 +                      ecc->layout = &nand_oob_128;
                        break;
                default:
                        pr_warn("No oob scheme defined for oobsize %d\n",
                                   mtd->oobsize);
 +                      BUG();
                }
        }
  
        if (!chip->write_page)
                chip->write_page = nand_write_page;
  
 -      /* set for ONFI nand */
 -      if (!chip->onfi_set_features)
 -              chip->onfi_set_features = nand_onfi_set_features;
 -      if (!chip->onfi_get_features)
 -              chip->onfi_get_features = nand_onfi_get_features;
 -
        /*
         * Check ECC mode, default to software if 3byte/512byte hardware ECC is
         * selected and we have 256 byte pagesize fallback to software ECC
         */
  
 -      switch (chip->ecc.mode) {
 +      switch (ecc->mode) {
        case NAND_ECC_HW_OOB_FIRST:
                /* Similar to NAND_ECC_HW, but a separate read_page handle */
 -              if (!chip->ecc.calculate || !chip->ecc.correct ||
 -                   !chip->ecc.hwctl) {
 +              if (!ecc->calculate || !ecc->correct || !ecc->hwctl) {
                        pr_warn("No ECC functions supplied; "
                                   "hardware ECC not possible\n");
                        BUG();
                }
 -              if (!chip->ecc.read_page)
 -                      chip->ecc.read_page = nand_read_page_hwecc_oob_first;
 +              if (!ecc->read_page)
 +                      ecc->read_page = nand_read_page_hwecc_oob_first;
  
        case NAND_ECC_HW:
                /* Use standard hwecc read page function? */
 -              if (!chip->ecc.read_page)
 -                      chip->ecc.read_page = nand_read_page_hwecc;
 -              if (!chip->ecc.write_page)
 -                      chip->ecc.write_page = nand_write_page_hwecc;
 -              if (!chip->ecc.read_page_raw)
 -                      chip->ecc.read_page_raw = nand_read_page_raw;
 -              if (!chip->ecc.write_page_raw)
 -                      chip->ecc.write_page_raw = nand_write_page_raw;
 -              if (!chip->ecc.read_oob)
 -                      chip->ecc.read_oob = nand_read_oob_std;
 -              if (!chip->ecc.write_oob)
 -                      chip->ecc.write_oob = nand_write_oob_std;
 +              if (!ecc->read_page)
 +                      ecc->read_page = nand_read_page_hwecc;
 +              if (!ecc->write_page)
 +                      ecc->write_page = nand_write_page_hwecc;
 +              if (!ecc->read_page_raw)
 +                      ecc->read_page_raw = nand_read_page_raw;
 +              if (!ecc->write_page_raw)
 +                      ecc->write_page_raw = nand_write_page_raw;
 +              if (!ecc->read_oob)
 +                      ecc->read_oob = nand_read_oob_std;
 +              if (!ecc->write_oob)
 +                      ecc->write_oob = nand_write_oob_std;
 +              if (!ecc->read_subpage)
 +                      ecc->read_subpage = nand_read_subpage;
 +              if (!ecc->write_subpage)
 +                      ecc->write_subpage = nand_write_subpage_hwecc;
  
        case NAND_ECC_HW_SYNDROME:
 -              if ((!chip->ecc.calculate || !chip->ecc.correct ||
 -                   !chip->ecc.hwctl) &&
 -                  (!chip->ecc.read_page ||
 -                   chip->ecc.read_page == nand_read_page_hwecc ||
 -                   !chip->ecc.write_page ||
 -                   chip->ecc.write_page == nand_write_page_hwecc)) {
 +              if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) &&
 +                  (!ecc->read_page ||
 +                   ecc->read_page == nand_read_page_hwecc ||
 +                   !ecc->write_page ||
 +                   ecc->write_page == nand_write_page_hwecc)) {
                        pr_warn("No ECC functions supplied; "
                                   "hardware ECC not possible\n");
                        BUG();
                }
                /* Use standard syndrome read/write page function? */
 -              if (!chip->ecc.read_page)
 -                      chip->ecc.read_page = nand_read_page_syndrome;
 -              if (!chip->ecc.write_page)
 -                      chip->ecc.write_page = nand_write_page_syndrome;
 -              if (!chip->ecc.read_page_raw)
 -                      chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
 -              if (!chip->ecc.write_page_raw)
 -                      chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
 -              if (!chip->ecc.read_oob)
 -                      chip->ecc.read_oob = nand_read_oob_syndrome;
 -              if (!chip->ecc.write_oob)
 -                      chip->ecc.write_oob = nand_write_oob_syndrome;
 -
 -              if (mtd->writesize >= chip->ecc.size) {
 -                      if (!chip->ecc.strength) {
 +              if (!ecc->read_page)
 +                      ecc->read_page = nand_read_page_syndrome;
 +              if (!ecc->write_page)
 +                      ecc->write_page = nand_write_page_syndrome;
 +              if (!ecc->read_page_raw)
 +                      ecc->read_page_raw = nand_read_page_raw_syndrome;
 +              if (!ecc->write_page_raw)
 +                      ecc->write_page_raw = nand_write_page_raw_syndrome;
 +              if (!ecc->read_oob)
 +                      ecc->read_oob = nand_read_oob_syndrome;
 +              if (!ecc->write_oob)
 +                      ecc->write_oob = nand_write_oob_syndrome;
 +
 +              if (mtd->writesize >= ecc->size) {
 +                      if (!ecc->strength) {
                                pr_warn("Driver must set ecc.strength when using hardware ECC\n");
                                BUG();
                        }
                }
                pr_warn("%d byte HW ECC not possible on "
                           "%d byte page size, fallback to SW ECC\n",
 -                         chip->ecc.size, mtd->writesize);
 -              chip->ecc.mode = NAND_ECC_SOFT;
 +                         ecc->size, mtd->writesize);
 +              ecc->mode = NAND_ECC_SOFT;
  
        case NAND_ECC_SOFT:
 -              chip->ecc.calculate = nand_calculate_ecc;
 -              chip->ecc.correct = nand_correct_data;
 -              chip->ecc.read_page = nand_read_page_swecc;
 -              chip->ecc.read_subpage = nand_read_subpage;
 -              chip->ecc.write_page = nand_write_page_swecc;
 -              chip->ecc.read_page_raw = nand_read_page_raw;
 -              chip->ecc.write_page_raw = nand_write_page_raw;
 -              chip->ecc.read_oob = nand_read_oob_std;
 -              chip->ecc.write_oob = nand_write_oob_std;
 -              if (!chip->ecc.size)
 -                      chip->ecc.size = 256;
 -              chip->ecc.bytes = 3;
 -              chip->ecc.strength = 1;
 +              ecc->calculate = nand_calculate_ecc;
 +              ecc->correct = nand_correct_data;
 +              ecc->read_page = nand_read_page_swecc;
 +              ecc->read_subpage = nand_read_subpage;
 +              ecc->write_page = nand_write_page_swecc;
 +              ecc->read_page_raw = nand_read_page_raw;
 +              ecc->write_page_raw = nand_write_page_raw;
 +              ecc->read_oob = nand_read_oob_std;
 +              ecc->write_oob = nand_write_oob_std;
 +              if (!ecc->size)
 +                      ecc->size = 256;
 +              ecc->bytes = 3;
 +              ecc->strength = 1;
                break;
  
        case NAND_ECC_SOFT_BCH:
                if (!mtd_nand_has_bch()) {
 -                      pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
 -                      return -EINVAL;
 +                      pr_warn("CONFIG_MTD_NAND_ECC_BCH not enabled\n");
 +                      BUG();
                }
 -              chip->ecc.calculate = nand_bch_calculate_ecc;
 -              chip->ecc.correct = nand_bch_correct_data;
 -              chip->ecc.read_page = nand_read_page_swecc;
 -              chip->ecc.read_subpage = nand_read_subpage;
 -              chip->ecc.write_page = nand_write_page_swecc;
 -              chip->ecc.read_page_raw = nand_read_page_raw;
 -              chip->ecc.write_page_raw = nand_write_page_raw;
 -              chip->ecc.read_oob = nand_read_oob_std;
 -              chip->ecc.write_oob = nand_write_oob_std;
 +              ecc->calculate = nand_bch_calculate_ecc;
 +              ecc->correct = nand_bch_correct_data;
 +              ecc->read_page = nand_read_page_swecc;
 +              ecc->read_subpage = nand_read_subpage;
 +              ecc->write_page = nand_write_page_swecc;
 +              ecc->read_page_raw = nand_read_page_raw;
 +              ecc->write_page_raw = nand_write_page_raw;
 +              ecc->read_oob = nand_read_oob_std;
 +              ecc->write_oob = nand_write_oob_std;
                /*
                 * Board driver should supply ecc.size and ecc.bytes values to
                 * select how many bits are correctable; see nand_bch_init()
                 * for details. Otherwise, default to 4 bits for large page
                 * devices.
                 */
 -              if (!chip->ecc.size && (mtd->oobsize >= 64)) {
 -                      chip->ecc.size = 512;
 -                      chip->ecc.bytes = 7;
 +              if (!ecc->size && (mtd->oobsize >= 64)) {
 +                      ecc->size = 512;
 +                      ecc->bytes = 7;
                }
 -              chip->ecc.priv = nand_bch_init(mtd,
 -                                             chip->ecc.size,
 -                                             chip->ecc.bytes,
 -                                             &chip->ecc.layout);
 -              if (!chip->ecc.priv)
 +              ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes,
 +                                             &ecc->layout);
 +              if (!ecc->priv) {
                        pr_warn("BCH ECC initialization failed!\n");
 -              chip->ecc.strength =
 -                      chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
 +                      BUG();
 +              }
 +              ecc->strength = ecc->bytes * 8 / fls(8 * ecc->size);
                break;
  
        case NAND_ECC_NONE:
                pr_warn("NAND_ECC_NONE selected by board driver. "
 -                      "This is not recommended !!\n");
 -              chip->ecc.read_page = nand_read_page_raw;
 -              chip->ecc.write_page = nand_write_page_raw;
 -              chip->ecc.read_oob = nand_read_oob_std;
 -              chip->ecc.read_page_raw = nand_read_page_raw;
 -              chip->ecc.write_page_raw = nand_write_page_raw;
 -              chip->ecc.write_oob = nand_write_oob_std;
 -              chip->ecc.size = mtd->writesize;
 -              chip->ecc.bytes = 0;
 +                         "This is not recommended!\n");
 +              ecc->read_page = nand_read_page_raw;
 +              ecc->write_page = nand_write_page_raw;
 +              ecc->read_oob = nand_read_oob_std;
 +              ecc->read_page_raw = nand_read_page_raw;
 +              ecc->write_page_raw = nand_write_page_raw;
 +              ecc->write_oob = nand_write_oob_std;
 +              ecc->size = mtd->writesize;
 +              ecc->bytes = 0;
 +              ecc->strength = 0;
                break;
  
        default:
 -              pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
 +              pr_warn("Invalid NAND_ECC_MODE %d\n", ecc->mode);
                BUG();
        }
  
        /* For many systems, the standard OOB write also works for raw */
 -      if (!chip->ecc.read_oob_raw)
 -              chip->ecc.read_oob_raw = chip->ecc.read_oob;
 -      if (!chip->ecc.write_oob_raw)
 -              chip->ecc.write_oob_raw = chip->ecc.write_oob;
 +      if (!ecc->read_oob_raw)
 +              ecc->read_oob_raw = ecc->read_oob;
 +      if (!ecc->write_oob_raw)
 +              ecc->write_oob_raw = ecc->write_oob;
  
        /*
         * The number of bytes available for a client to place data into
         * the out of band area.
         */
 -      chip->ecc.layout->oobavail = 0;
 -      for (i = 0; chip->ecc.layout->oobfree[i].length
 -                      && i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)
 -              chip->ecc.layout->oobavail +=
 -                      chip->ecc.layout->oobfree[i].length;
 -      mtd->oobavail = chip->ecc.layout->oobavail;
 +      ecc->layout->oobavail = 0;
 +      for (i = 0; ecc->layout->oobfree[i].length
 +                      && i < ARRAY_SIZE(ecc->layout->oobfree); i++)
 +              ecc->layout->oobavail += ecc->layout->oobfree[i].length;
 +      mtd->oobavail = ecc->layout->oobavail;
  
        /*
         * Set the number of read / write steps for one page depending on ECC
         * mode.
         */
 -      chip->ecc.steps = mtd->writesize / chip->ecc.size;
 -      if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
 +      ecc->steps = mtd->writesize / ecc->size;
 +      if (ecc->steps * ecc->size != mtd->writesize) {
                pr_warn("Invalid ECC parameters\n");
+               pr_warn("steps=%d size=%d writesize=%d\n",
+                       chip->ecc.steps, chip->ecc.size, mtd->writesize);
                BUG();
        }
 -      chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 +      ecc->total = ecc->steps * ecc->bytes;
  
        /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
 -      if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
 -          !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
 -              switch (chip->ecc.steps) {
 +      if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
 +              switch (ecc->steps) {
                case 2:
                        mtd->subpage_sft = 1;
                        break;
        /* Initialize state */
        chip->state = FL_READY;
  
 -      /* De-select the device */
 -      chip->select_chip(mtd, -1);
 -
        /* Invalidate the pagebuffer reference */
        chip->pagebuf = -1;
  
        /* Large page NAND with SOFT_ECC should support subpage reads */
 -      if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
 +      if ((ecc->mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
                chip->options |= NAND_SUBPAGE_READ;
  
        /* Fill in remaining MTD driver data */
 -      mtd->type = MTD_NANDFLASH;
 +      mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
                                                MTD_CAP_NANDFLASH;
        mtd->_erase = nand_erase;
 +#ifndef __UBOOT__
        mtd->_point = NULL;
        mtd->_unpoint = NULL;
 +#endif
        mtd->_read = nand_read;
        mtd->_write = nand_write;
 +      mtd->_panic_write = panic_nand_write;
        mtd->_read_oob = nand_read_oob;
        mtd->_write_oob = nand_write_oob;
        mtd->_sync = nand_sync;
        mtd->_lock = NULL;
        mtd->_unlock = NULL;
 +#ifndef __UBOOT__
 +      mtd->_suspend = nand_suspend;
 +      mtd->_resume = nand_resume;
 +#endif
        mtd->_block_isbad = nand_block_isbad;
        mtd->_block_markbad = nand_block_markbad;
 +      mtd->writebufsize = mtd->writesize;
  
        /* propagate ecc info to mtd_info */
 -      mtd->ecclayout = chip->ecc.layout;
 -      mtd->ecc_strength = chip->ecc.strength;
 +      mtd->ecclayout = ecc->layout;
 +      mtd->ecc_strength = ecc->strength;
 +      mtd->ecc_step_size = ecc->size;
        /*
         * Initialize bitflip_threshold to its default prior scan_bbt() call.
         * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
        if (!mtd->bitflip_threshold)
                mtd->bitflip_threshold = mtd->ecc_strength;
  
 -      /* Check, if we should skip the bad block table scan */
 -      if (chip->options & NAND_SKIP_BBTSCAN)
 -              chip->options |= NAND_BBT_SCANNED;
 -
        return 0;
  }
 +EXPORT_SYMBOL(nand_scan_tail);
 +
 +/*
 + * is_module_text_address() isn't exported, and it's mostly a pointless
 + * test if this is a module _anyway_ -- they'd have to try _really_ hard
 + * to call us from in-kernel code if the core NAND support is modular.
 + */
 +#ifdef MODULE
 +#define caller_is_module() (1)
 +#else
 +#define caller_is_module() \
 +      is_module_text_address((unsigned long)__builtin_return_address(0))
 +#endif
  
  /**
   * nand_scan - [NAND Interface] Scan for the NAND device
@@@ -4356,20 -3394,12 +4358,20 @@@ int nand_scan(struct mtd_info *mtd, in
  {
        int ret;
  
 +      /* Many callers got this wrong, so check for it for a while... */
 +      if (!mtd->owner && caller_is_module()) {
 +              pr_crit("%s called with NULL mtd->owner!\n", __func__);
 +              BUG();
 +      }
 +
        ret = nand_scan_ident(mtd, maxchips, NULL);
        if (!ret)
                ret = nand_scan_tail(mtd);
        return ret;
  }
 +EXPORT_SYMBOL(nand_scan);
  
 +#ifndef __UBOOT__
  /**
   * nand_release - [NAND Interface] Free resources held by the NAND device
   * @mtd: MTD device structure
@@@ -4381,7 -3411,10 +4383,7 @@@ void nand_release(struct mtd_info *mtd
        if (chip->ecc.mode == NAND_ECC_SOFT_BCH)
                nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
  
 -#ifdef CONFIG_MTD_PARTITIONS
 -      /* Deregister partitions */
 -      del_mtd_partitions(mtd);
 -#endif
 +      mtd_device_unregister(mtd);
  
        /* Free bad block table memory */
        kfree(chip->bbt);
                        & NAND_BBT_DYNAMICSTRUCT)
                kfree(chip->badblock_pattern);
  }
 +EXPORT_SYMBOL_GPL(nand_release);
 +
 +static int __init nand_base_init(void)
 +{
 +      led_trigger_register_simple("nand-disk", &nand_led_trigger);
 +      return 0;
 +}
 +
 +static void __exit nand_base_exit(void)
 +{
 +      led_trigger_unregister_simple(nand_led_trigger);
 +}
 +#endif
 +
 +module_init(nand_base_init);
 +module_exit(nand_base_exit);
 +
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
 +MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
 +MODULE_DESCRIPTION("Generic NAND flash driver code");
index 700ca324e21418bd3416599a2bc9726c007fdf03,664dfc5dd9f3c81c34e4fc6fc09b1af015dd38b6..24cbac80a25e32f27a7a297cbe95164eaf923cf8
@@@ -78,7 -78,7 +78,7 @@@ static int nand_command(int block, int 
        }
  
        /* Shift the offset from byte addressing to word addressing. */
 -      if (this->options & NAND_BUSWIDTH_16)
 +      if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
                offs >>= 1;
  
        /* Begin command latch cycle */
@@@ -208,9 -208,16 +208,16 @@@ static int nand_read_page(int block, in
  
  int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
  {
-       unsigned int block, lastblock;
+       unsigned int block, lastblock, bad = 0;
        unsigned int page;
+       const int ppb = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
+       int maxbad;
  
+ #ifdef CONFIG_SYS_NAND_MAXBAD
+       maxbad = CONFIG_SYS_NAND_MAXBAD;
+ #else
+       maxbad = mtd.size;
+ #endif
        /*
         * offs has to be aligned to a page address!
         */
                         * Skip bad blocks
                         */
                        while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
-                               nand_read_page(block, page, dst);
+                               if (nand_chip.ecc.read_page) {
+                                       int ret;
+                                       ret = nand_chip.ecc.read_page(&mtd, &nand_chip,
+                                               dst, block * ppb + page);
+                                       if (ret) {
+                                               if (page > 0)
+                                                       dst -= (page - 1) * CONFIG_SYS_NAND_PAGE_SIZE;
+                                               bad++;
+                                               lastblock++;
+                                               break;
+                                       }
+                               } else {
+                                       nand_read_page(block, page, dst);
+                               }
                                dst += CONFIG_SYS_NAND_PAGE_SIZE;
                                page++;
                        }
  
                        page = 0;
                } else {
+                       printf("Skipping bad block %d\n", block);
+                       bad++;
                        lastblock++;
                }
  
+               if (maxbad > 0 && bad > maxbad) {
+                       printf("Too many bad blocks encountered\n");
+                       return -1;
+               }
                block++;
        }
  
  /* nand_init() - initialize data to make nand usable by SPL */
  void nand_init(void)
  {
+       static struct nand_buffers ecc_buf;
        /*
         * Init board specific nand support
         */
        mtd.priv = &nand_chip;
+       mtd.erasesize = CONFIG_SYS_NAND_BLOCK_SIZE;
+       mtd.writesize = CONFIG_SYS_NAND_PAGE_SIZE;
+       mtd.oobsize = CONFIG_SYS_NAND_OOBSIZE;
        nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
                (void  __iomem *)CONFIG_SYS_NAND_BASE;
+       nand_chip.oob_poi = ecc_buf.databuf;
+       nand_chip.buffers = &ecc_buf;
        board_nand_init(&nand_chip);
  
  #ifdef CONFIG_SPL_NAND_SOFTECC
index 459904d81c21a2356e353c642ef065151006c257,06646443ec2ec2692a4d5ec857807e06999a0463..f809a783a5bbe9c2fde767484e91f51c67802469
  #include <asm/io.h>
  #include <asm/errno.h>
  #include <asm/arch/mem.h>
 -#include <asm/arch/cpu.h>
 -#include <asm/omap_gpmc.h>
 +#include <linux/mtd/omap_gpmc.h>
  #include <linux/mtd/nand_ecc.h>
  #include <linux/bch.h>
  #include <linux/compiler.h>
  #include <nand.h>
 -#ifdef CONFIG_AM33XX
 -#include <asm/arch/elm.h>
 +#include <linux/mtd/omap_elm.h>
 +
 +#define BADBLOCK_MARKER_LENGTH        2
 +#define SECTOR_BYTES          512
 +#define ECCCLEAR              (0x1 << 8)
 +#define ECCRESULTREG1         (0x1 << 0)
 +/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
 +#define BCH4_BIT_PAD          4
 +
 +#ifdef CONFIG_BCH
 +static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
 +                              0x97, 0x79, 0xe5, 0x24, 0xb5};
  #endif
 +static uint8_t cs_next;
 +static __maybe_unused struct nand_ecclayout omap_ecclayout;
  
 -static uint8_t cs;
 -static __maybe_unused struct nand_ecclayout hw_nand_oob =
 -      GPMC_NAND_HW_ECC_LAYOUT;
 -static __maybe_unused struct nand_ecclayout hw_bch8_nand_oob =
 -      GPMC_NAND_HW_BCH8_ECC_LAYOUT;
 +/*
 + * Driver configurations
 + */
 +struct omap_nand_info {
 +      struct bch_control *control;
 +      enum omap_ecc ecc_scheme;
 +      int cs;
 +};
 +
 +/* We are wasting a bit of memory but al least we are safe */
 +static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
  
+ static struct gpmc __iomem *gpmc_cfg = (void __iomem *)GPMC_BASE;
+ #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+ static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+ static struct nand_bbt_descr bbt_main_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+               NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 0, /* may be overwritten depending on ECC layout */
+       .len = 4,
+       .veroffs = 4, /* may be overwritten depending on ECC layout */
+       .maxblocks = 4,
+       .pattern = bbt_pattern,
+ };
+ static struct nand_bbt_descr bbt_mirror_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+               NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 0, /* may be overwritten depending on ECC layout */
+       .len = 4,
+       .veroffs = 4, /* may be overwritten depending on ECC layout */
+       .maxblocks = 4,
+       .pattern = mirror_pattern,
+ };
+ #endif
+ #define PREFETCH_FIFOTHRESHOLD_MAX            0x40
+ #define PREFETCH_FIFOTHRESHOLD(val)           ((val) << 8)
+ #define PREFETCH_ENABLEOPTIMIZEDACCESS                (0x1 << 27)
+ #define GPMC_PREFETCH_STATUS_FIFO_CNT(val)    (((val) >> 24) & 0x7F)
+ #define GPMC_PREFETCH_STATUS_COUNT(val)               ((val) & 0x00003fff)
+ #define CS_NUM_SHIFT                          24
+ #define ENABLE_PREFETCH                               (0x1 << 7)
+ #define DMA_MPU_MODE                          2
+ #define OMAP_NAND_TIMEOUT_MS                  5000
+ #define PRINT_REG(x) debug("+++ %.15s (0x%08x)=0x%08x\n", #x, &gpmc_cfg->x, readl(&gpmc_cfg->x))
+ #ifdef CONFIG_SYS_GPMC_PREFETCH_ENABLE
+ /**
+  * gpmc_prefetch_enable - configures and starts prefetch transfer
+  * @cs: cs (chip select) number
+  * @fifo_th: fifo threshold to be used for read/ write
+  * @count: number of bytes to be transferred
+  * @is_write: prefetch read(0) or write post(1) mode
+  */
+ static inline void gpmc_prefetch_enable(int cs, int fifo_th,
+                                       unsigned int count, int is_write)
+ {
+       writel(count, &gpmc_cfg->pref_config2);
+       /* Set the prefetch read / post write and enable the engine.
+        * Set which cs is has requested for.
+        */
+       uint32_t val = (cs << CS_NUM_SHIFT) |
+               PREFETCH_ENABLEOPTIMIZEDACCESS |
+               PREFETCH_FIFOTHRESHOLD(fifo_th) |
+               ENABLE_PREFETCH |
+               !!is_write;
+       writel(val, &gpmc_cfg->pref_config1);
+       /*  Start the prefetch engine */
+       writel(0x1, &gpmc_cfg->pref_control);
+ }
+ /**
+  * gpmc_prefetch_reset - disables and stops the prefetch engine
+  */
+ static inline void gpmc_prefetch_reset(void)
+ {
+       /* Stop the PFPW engine */
+       writel(0x0, &gpmc_cfg->pref_control);
+       /* Reset/disable the PFPW engine */
+       writel(0x0, &gpmc_cfg->pref_config1);
+ }
+ //#define FIFO_IOADDR         (nand->IO_ADDR_R)
+ #define FIFO_IOADDR           PISMO1_NAND_BASE
+ /**
+  * read_buf_pref - read data from NAND controller into buffer
+  * @mtd: MTD device structure
+  * @buf: buffer to store date
+  * @len: number of bytes to read
+  */
+ static void read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
+ {
+       gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 0);
+       do {
+               // Get number of bytes waiting in the FIFO
+               uint32_t read_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+               if (read_bytes == 0)
+                       continue;
+               // Alignment of Destination Buffer
+               while (read_bytes && ((unsigned int)buf & 3)) {
+                       *buf++ = readb(FIFO_IOADDR);
+                       read_bytes--;
+                       len--;
+               }
+               // Use maximum word size (32bit) inside this loop, because speed is limited by
+               // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+               len -= read_bytes & ~3;
+               while (read_bytes >= 4) {
+                       *((uint32_t*)buf) = readl(FIFO_IOADDR);
+                       buf += 4;
+                       read_bytes -= 4;
+               }
+               // Transfer the last (non-aligned) bytes only at the last iteration,
+               // to maintain full speed up to the end of the transfer.
+               if (read_bytes == len) {
+                       while (read_bytes) {
+                               *buf++ = readb(FIFO_IOADDR);
+                               read_bytes--;
+                       }
+                       len = 0;
+               }
+       } while (len > 0);
+       gpmc_prefetch_reset();
+ }
+ /*
+  * write_buf_pref - write buffer to NAND controller
+  * @mtd: MTD device structure
+  * @buf: data buffer
+  * @len: number of bytes to write
+  */
+ static void write_buf_pref(struct mtd_info *mtd, const u_char *buf, int len)
+ {
+       /*  configure and start prefetch transfer */
+       gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 1);
+       while (len) {
+               // Get number of free bytes in the FIFO
+               uint32_t write_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+               // don't write more bytes than requested
+               if (write_bytes > len)
+                       write_bytes = len;
+               // Alignment of Source Buffer
+               while (write_bytes && ((unsigned int)buf & 3)) {
+                       writeb(*buf++, FIFO_IOADDR);
+                       write_bytes--;
+                       len--;
+               }
+               // Use maximum word size (32bit) inside this loop, because speed is limited by
+               // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+               len -= write_bytes & ~3;
+               while (write_bytes >= 4) {
+                       writel(*((uint32_t*)buf), FIFO_IOADDR);
+                       buf += 4;
+                       write_bytes -= 4;
+               }
+               // Transfer the last (non-aligned) bytes only at the last iteration,
+               // to maintain full speed up to the end of the transfer.
+               if (write_bytes == len) {
+                       while (write_bytes) {
+                               writeb(*buf++, FIFO_IOADDR);
+                               write_bytes--;
+                       }
+                       len = 0;
+               }
+       }
+       /* wait for data to be flushed out before resetting the prefetch */
+       while ((len = GPMC_PREFETCH_STATUS_COUNT(readl(&gpmc_cfg->pref_status)))) {
+               debug("%u bytes still in FIFO\n", PREFETCH_FIFOTHRESHOLD_MAX - len);
+               ndelay(1);
+       }
+       /* disable and stop the PFPW engine */
+       gpmc_prefetch_reset();
+ }
+ #endif /* CONFIG_SYS_GPMC_PREFETCH_ENABLE */
  /*
   * omap_nand_hwcontrol - Set the address pointers corretly for the
   *                    following address/data/command operation
@@@ -50,8 -217,6 +234,8 @@@ static void omap_nand_hwcontrol(struct 
                                uint32_t ctrl)
  {
        register struct nand_chip *this = mtd->priv;
 +      struct omap_nand_info *info = this->priv;
 +      int cs = info->cs;
  
        /*
         * Point the IO_ADDR to DATA and ADDRESS registers instead
                writeb(cmd, this->IO_ADDR_W);
  }
  
 -#ifdef CONFIG_SPL_BUILD
  /* Check wait pin as dev ready indicator */
 -int omap_spl_dev_ready(struct mtd_info *mtd)
 +static int omap_dev_ready(struct mtd_info *mtd)
  {
-       return gpmc_cfg->status & (1 << 8);
+       return readl(&gpmc_cfg->status) & (1 << 8);
  }
 -#endif
 -
 -/*
 - * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
 - *                   GPMC controller
 - * @mtd:        MTD device structure
 - *
 - */
 -static void __maybe_unused omap_hwecc_init(struct nand_chip *chip)
 -{
 -      /*
 -       * Init ECC Control Register
 -       * Clear all ECC | Enable Reg1
 -       */
 -      writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 -      writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_cfg->ecc_size_config);
 -}
  
  /*
   * gen_true_ecc - This function will generate true ECC value, which
@@@ -159,191 -342,366 +343,191 @@@ static int __maybe_unused omap_correct_
  }
  
  /*
 - *  omap_calculate_ecc - Generate non-inverted ECC bytes.
 - *
 - *  Using noninverted ECC can be considered ugly since writing a blank
 - *  page ie. padding will clear the ECC bytes. This is no problem as
 - *  long nobody is trying to write data on the seemingly unused page.
 - *  Reading an erased page will produce an ECC mismatch between
 - *  generated and read ECC bytes that has to be dealt with separately.
 - *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
 - *  is used, the result of read will be 0x0 while the ECC offsets of the
 - *  spare area will be 0xFF which will result in an ECC mismatch.
 - *  @mtd:     MTD structure
 - *  @dat:     unused
 - *  @ecc_code:        ecc_code buffer
 - */
 -static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
 -              const uint8_t *dat, uint8_t *ecc_code)
 -{
 -      u_int32_t val;
 -
 -      /* Start Reading from HW ECC1_Result = 0x200 */
 -      val = readl(&gpmc_cfg->ecc1_result);
 -
 -      ecc_code[0] = val & 0xFF;
 -      ecc_code[1] = (val >> 16) & 0xFF;
 -      ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
 -
 -      /*
 -       * Stop reading anymore ECC vals and clear old results
 -       * enable will be called if more reads are required
 -       */
 -      writel(0x000, &gpmc_cfg->ecc_config);
 -
 -      return 0;
 -}
 -
 -/*
 - * omap_enable_ecc - This function enables the hardware ecc functionality
 - * @mtd:        MTD device structure
 - * @mode:       Read/Write mode
 - */
 -static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 -{
 -      struct nand_chip *chip = mtd->priv;
 -      uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
 -
 -      switch (mode) {
 -      case NAND_ECC_READ:
 -      case NAND_ECC_WRITE:
 -              /* Clear the ecc result registers, select ecc reg as 1 */
 -              writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 -
 -              /*
 -               * Size 0 = 0xFF, Size1 is 0xFF - both are 512 bytes
 -               * tell all regs to generate size0 sized regs
 -               * we just have a single ECC engine for all CS
 -               */
 -              writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
 -                      &gpmc_cfg->ecc_size_config);
 -              val = (dev_width << 7) | (cs << 1) | (1 << 0);
 -              writel(val, &gpmc_cfg->ecc_config);
 -              break;
 -      default:
 -              printf("Error: Unrecognized Mode[%d]!\n", mode);
 -      }
 -}
 -
 -/*
 - * Generic BCH interface
 - */
 -struct nand_bch_priv {
 -      uint8_t mode;
 -      uint8_t type;
 -      uint8_t nibbles;
 -      struct bch_control *control;
 -};
 -
 -/* bch types */
 -#define ECC_BCH4      0
 -#define ECC_BCH8      1
 -#define ECC_BCH16     2
 -
 -/* GPMC ecc engine settings */
 -#define BCH_WRAPMODE_1                1       /* BCH wrap mode 1 */
 -#define BCH_WRAPMODE_6                6       /* BCH wrap mode 6 */
 -
 -/* BCH nibbles for diff bch levels */
 -#define NAND_ECC_HW_BCH ((uint8_t)(NAND_ECC_HW_OOB_FIRST) + 1)
 -#define ECC_BCH4_NIBBLES      13
 -#define ECC_BCH8_NIBBLES      26
 -#define ECC_BCH16_NIBBLES     52
 -
 -/*
 - * This can be a single instance cause all current users have only one NAND
 - * with nearly the same setup (BCH8, some with ELM and others with sw BCH
 - * library).
 - * When some users with other BCH strength will exists this have to change!
 - */
 -static __maybe_unused struct nand_bch_priv bch_priv = {
 -      .mode = NAND_ECC_HW_BCH,
 -      .type = ECC_BCH8,
 -      .nibbles = ECC_BCH8_NIBBLES,
 -      .control = NULL,
 -};
 -
 -/*
 - * omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
 - *                            GPMC controller
 + * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
   * @mtd:      MTD device structure
   * @mode:     Read/Write mode
   */
  __maybe_unused
 -static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
 +static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
  {
 -      uint32_t val;
 -      uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
 -#ifdef CONFIG_AM33XX
 -      uint32_t unused_length = 0;
 -#endif
 -      uint32_t wr_mode = BCH_WRAPMODE_6;
 -      struct nand_bch_priv *bch = chip->priv;
 -
 -      /* Clear the ecc result registers, select ecc reg as 1 */
 -      writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 -
 -#ifdef CONFIG_AM33XX
 -      wr_mode = BCH_WRAPMODE_1;
 -
 -      switch (bch->nibbles) {
 -      case ECC_BCH4_NIBBLES:
 -              unused_length = 3;
 -              break;
 -      case ECC_BCH8_NIBBLES:
 -              unused_length = 2;
 +      struct nand_chip        *nand   = mtd->priv;
 +      struct omap_nand_info   *info   = nand->priv;
 +      unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
 +      unsigned int ecc_algo = 0;
 +      unsigned int bch_type = 0;
 +      unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
 +      u32 ecc_size_config_val = 0;
 +      u32 ecc_config_val = 0;
 +      int cs = info->cs;
 +
 +      /* configure GPMC for specific ecc-scheme */
 +      switch (info->ecc_scheme) {
 +      case OMAP_ECC_HAM1_CODE_SW:
 +              return;
 +      case OMAP_ECC_HAM1_CODE_HW:
 +              ecc_algo = 0x0;
 +              bch_type = 0x0;
 +              bch_wrapmode = 0x00;
 +              eccsize0 = 0xFF;
 +              eccsize1 = 0xFF;
                break;
 -      case ECC_BCH16_NIBBLES:
 -              unused_length = 0;
 +      case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 +      case OMAP_ECC_BCH8_CODE_HW:
 +              ecc_algo = 0x1;
 +              bch_type = 0x1;
 +              if (mode == NAND_ECC_WRITE) {
 +                      bch_wrapmode = 0x01;
 +                      eccsize0 = 0;  /* extra bits in nibbles per sector */
 +                      eccsize1 = 28; /* OOB bits in nibbles per sector */
 +              } else {
 +                      bch_wrapmode = 0x01;
 +                      eccsize0 = 26; /* ECC bits in nibbles per sector */
 +                      eccsize1 = 2;  /* non-ECC bits in nibbles per sector */
 +              }
                break;
 -      }
 -
 -      /*
 -       * This is ecc_size_config for ELM mode.
 -       * Here we are using different settings for read and write access and
 -       * also depending on BCH strength.
 -       */
 -      switch (mode) {
 -      case NAND_ECC_WRITE:
 -              /* write access only setup eccsize1 config */
 -              val = ((unused_length + bch->nibbles) << 22);
 +      case OMAP_ECC_BCH16_CODE_HW:
 +              ecc_algo = 0x1;
 +              bch_type = 0x2;
 +              if (mode == NAND_ECC_WRITE) {
 +                      bch_wrapmode = 0x01;
 +                      eccsize0 = 0;  /* extra bits in nibbles per sector */
 +                      eccsize1 = 52; /* OOB bits in nibbles per sector */
 +              } else {
 +                      bch_wrapmode = 0x01;
 +                      eccsize0 = 52; /* ECC bits in nibbles per sector */
 +                      eccsize1 = 0;  /* non-ECC bits in nibbles per sector */
 +              }
                break;
 -
 -      case NAND_ECC_READ:
        default:
 -              /*
 -               * by default eccsize0 selected for ecc1resultsize
 -               * eccsize0 config.
 -               */
 -              val  = (bch->nibbles << 12);
 -              /* eccsize1 config */
 -              val |= (unused_length << 22);
 -              break;
 +              return;
        }
 -#else
 -      /*
 -       * This ecc_size_config setting is for BCH sw library.
 -       *
 -       * Note: we only support BCH8 currently with BCH sw library!
 -       * Should be really easy to adopt to BCH4, however some omap3 have
 -       * flaws with BCH4.
 -       *
 -       * Here we are using wrapping mode 6 both for reading and writing, with:
 -       *  size0 = 0  (no additional protected byte in spare area)
 -       *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
 -       */
 -      val = (32 << 22) | (0 << 12);
 -#endif
 -      /* ecc size configuration */
 -      writel(val, &gpmc_cfg->ecc_size_config);
 -
 -      /*
 -       * Configure the ecc engine in gpmc
 -       * We assume 512 Byte sector pages for access to NAND.
 -       */
 -      val  = 1 << 16;                 /* select BCH mode */
 -      val |= bch->type << 12;         /* setup BCH type */
 -      val |= wr_mode << 8;            /* setup wrapping mode */
 -      val |= dev_width << 7;          /* setup device width (16 or 8 bit) */
 -      val |= (chip->ecc.size / 512 - 1) << 4; /* set ECC size */
 -      val |= cs << 1;                 /* setup chip select to work on */
 -      val |= 1 << 0;                  /* enable ECC engine */
 -
 -      debug("set ECC_CONFIG=0x%08x\n", val);
 -      writel(val, &gpmc_cfg->ecc_config);
 -}
 -
 -/*
 - * omap_enable_ecc_bch - This function enables the bch h/w ecc functionality
 - * @mtd:      MTD device structure
 - * @mode:     Read/Write mode
 - */
 -__maybe_unused
 -static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
 -{
 -      struct nand_chip *chip = mtd->priv;
 -
 -      omap_hwecc_init_bch(chip, mode);
 -}
 -
 -/*
 - * omap_ecc_disable - Disable H/W ECC calculation
 - *
 - * @mtd:      MTD device structure
 - */
 -static void __maybe_unused omap_ecc_disable(struct mtd_info *mtd)
 -{
 -      writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config);
 +      /* Clear ecc and enable bits */
 +      writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 +      /* Configure ecc size for BCH */
 +      ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
 +      writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
 +
 +      /* Configure device details for BCH engine */
 +      ecc_config_val = ((ecc_algo << 16)      | /* HAM1 | BCHx */
 +                      (bch_type << 12)        | /* BCH4/BCH8/BCH16 */
 +                      (bch_wrapmode << 8)     | /* wrap mode */
 +                      (dev_width << 7)        | /* bus width */
 +                      (0x0 << 4)              | /* number of sectors */
 +                      (cs <<  1)              | /* ECC CS */
 +                      (0x1));                   /* enable ECC */
 +      writel(ecc_config_val, &gpmc_cfg->ecc_config);
  }
  
  /*
 - * BCH8 support (needs ELM and thus AM33xx-only)
 - */
 -#ifdef CONFIG_AM33XX
 -/*
 - * omap_read_bch8_result - Read BCH result for BCH8 level
 - *
 - * @mtd:      MTD device structure
 - * @big_endian:       When set read register 3 first
 - * @ecc_code: Read syndrome from BCH result registers
 + *  omap_calculate_ecc - Read ECC result
 + *  @mtd:     MTD structure
 + *  @dat:     unused
 + *  @ecc_code:        ecc_code buffer
 + *  Using noninverted ECC can be considered ugly since writing a blank
 + *  page ie. padding will clear the ECC bytes. This is no problem as
 + *  long nobody is trying to write data on the seemingly unused page.
 + *  Reading an erased page will produce an ECC mismatch between
 + *  generated and read ECC bytes that has to be dealt with separately.
 + *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
 + *  is used, the result of read will be 0x0 while the ECC offsets of the
 + *  spare area will be 0xFF which will result in an ECC mismatch.
   */
 -static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
 +static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
                                uint8_t *ecc_code)
  {
 -      uint32_t *ptr;
 -      int8_t i = 0, j, k;
        struct nand_chip *chip = mtd->priv;
 -      int num_steps = chip->ecc.size / 512;
 -
 -      for (k = 0; k < num_steps; k++) {
 -              if (big_endian) {
 -                      ptr = &gpmc_cfg->bch_result_0_3[k].bch_result_x[3];
 -                      ecc_code[i++] = readl(ptr) & 0xFF;
 +      struct omap_nand_info *info = chip->priv;
 +      uint32_t *ptr, val = 0;
 +      int8_t i = 0, j;
 +
 +      switch (info->ecc_scheme) {
 +      case OMAP_ECC_HAM1_CODE_HW:
 +              val = readl(&gpmc_cfg->ecc1_result);
 +              ecc_code[0] = val & 0xFF;
 +              ecc_code[1] = (val >> 16) & 0xFF;
 +              ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
 +              break;
 +#ifdef CONFIG_BCH
 +      case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 +#endif
 +      case OMAP_ECC_BCH8_CODE_HW:
 +              ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
 +              val = readl(ptr);
 +              ecc_code[i++] = (val >>  0) & 0xFF;
 +              ptr--;
 +              for (j = 0; j < 3; j++) {
 +                      val = readl(ptr);
 +                      ecc_code[i++] = (val >> 24) & 0xFF;
 +                      ecc_code[i++] = (val >> 16) & 0xFF;
 +                      ecc_code[i++] = (val >>  8) & 0xFF;
 +                      ecc_code[i++] = (val >>  0) & 0xFF;
                        ptr--;
 -                      for (j = 0; j < 3; j++) {
 -                              ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
 -                              ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
 -                              ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
 -                              ecc_code[i++] = readl(ptr) & 0xFF;
 -                              ptr--;
 -                      }
 -              } else {
 -                      ptr = &gpmc_cfg->bch_result_0_3[k].bch_result_x[0];
 -                      for (j = 0; j < 3; j++) {
 -                              ecc_code[i++] = readl(ptr) & 0xFF;
 -                              ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
 -                              ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
 -                              ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
 -                              ptr++;
 -                      }
 -                      ecc_code[i++] = readl(ptr) & 0xFF;
                }
 -              ecc_code[i++] = 0;      /* 14th byte is always zero */
 +              break;
 +      case OMAP_ECC_BCH16_CODE_HW:
 +              val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
 +              ecc_code[i++] = (val >>  8) & 0xFF;
 +              ecc_code[i++] = (val >>  0) & 0xFF;
 +              val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
 +              ecc_code[i++] = (val >> 24) & 0xFF;
 +              ecc_code[i++] = (val >> 16) & 0xFF;
 +              ecc_code[i++] = (val >>  8) & 0xFF;
 +              ecc_code[i++] = (val >>  0) & 0xFF;
 +              val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
 +              ecc_code[i++] = (val >> 24) & 0xFF;
 +              ecc_code[i++] = (val >> 16) & 0xFF;
 +              ecc_code[i++] = (val >>  8) & 0xFF;
 +              ecc_code[i++] = (val >>  0) & 0xFF;
 +              for (j = 3; j >= 0; j--) {
 +                      val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
 +                                                                      );
 +                      ecc_code[i++] = (val >> 24) & 0xFF;
 +                      ecc_code[i++] = (val >> 16) & 0xFF;
 +                      ecc_code[i++] = (val >>  8) & 0xFF;
 +                      ecc_code[i++] = (val >>  0) & 0xFF;
 +              }
 +              break;
 +      default:
 +              return -EINVAL;
        }
 -}
 -
 -/*
 - * omap_rotate_ecc_bch - Rotate the syndrome bytes
 - *
 - * @mtd:      MTD device structure
 - * @calc_ecc: ECC read from ECC registers
 - * @syndrome: Rotated syndrome will be returned in this array
 - *
 - */
 -static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
 -              uint8_t *syndrome)
 -{
 -      struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *bch = chip->priv;
 -      uint8_t n_bytes = 0;
 -      int8_t i, j;
 -
 -      switch (bch->type) {
 -      case ECC_BCH4:
 -              n_bytes = 8;
 +      /* ECC scheme specific syndrome customizations */
 +      switch (info->ecc_scheme) {
 +      case OMAP_ECC_HAM1_CODE_HW:
                break;
 +#ifdef CONFIG_BCH
 +      case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
  
 -      case ECC_BCH16:
 -              n_bytes = 28;
 +              for (i = 0; i < chip->ecc.bytes; i++)
 +                      *(ecc_code + i) = *(ecc_code + i) ^
 +                                              bch8_polynomial[i];
                break;
 -
 -      case ECC_BCH8:
 -      default:
 -              n_bytes = 13;
 +#endif
 +      case OMAP_ECC_BCH8_CODE_HW:
 +              ecc_code[chip->ecc.bytes - 1] = 0x00;
                break;
 +      case OMAP_ECC_BCH16_CODE_HW:
 +              break;
 +      default:
 +              return -EINVAL;
        }
 -
 -      for (i = 0, j = n_bytes - 1; i < n_bytes; i++, j--)
 -              syndrome[i] =  calc_ecc[j];
 +      return 0;
  }
  
 +#ifdef CONFIG_NAND_OMAP_ELM
  /*
 - *  omap_calculate_ecc_bch - Read BCH ECC result
 - *
 - *  @mtd:     MTD structure
 - *  @dat:     unused
 - *  @ecc_code:        ecc_code buffer
 - */
 -static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
 -                              uint8_t *ecc_code)
 + * 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)
  {
 -      struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *bch = chip->priv;
 -      uint8_t big_endian = 1;
 -      int8_t ret = 0;
 -
 -      if (bch->type == ECC_BCH8)
 -              omap_read_bch8_result(mtd, big_endian, ecc_code);
 -      else /* BCH4 and BCH16 currently not supported */
 -              ret = -1;
 -
 -      /*
 -       * Stop reading anymore ECC vals and clear old results
 -       * enable will be called if more reads are required
 -       */
 -      omap_ecc_disable(mtd);
 -
 -      return ret;
 -}
 -
 -/*
 - * omap_fix_errors_bch - Correct bch error in the data
 - *
 - * @mtd:      MTD device structure
 - * @data:     Data read from flash
 - * @error_count:Number of errors in data
 - * @error_loc:        Locations of errors in the data
 - *
 - */
 -static void omap_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
 -              uint32_t error_count, uint32_t *error_loc)
 -{
 -      struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *bch = chip->priv;
 -      uint8_t count = 0;
 -      uint32_t error_byte_pos;
 -      uint32_t error_bit_mask;
 -      uint32_t last_bit = (bch->nibbles * 4) - 1;
 -
 -      /* Flip all bits as specified by the error location array. */
 -      /* FOR( each found error location flip the bit ) */
 -      for (count = 0; count < error_count; count++) {
 -              if (error_loc[count] > last_bit) {
 -                      /* Remove the ECC spare bits from correction. */
 -                      error_loc[count] -= (last_bit + 1);
 -                      /* Offset bit in data region */
 -                      error_byte_pos = ((512 * 8) -
 -                                      (error_loc[count]) - 1) / 8;
 -                      /* Error Bit mask */
 -                      error_bit_mask = 0x1 << (error_loc[count] % 8);
 -                      /* Toggle the error bit to make the correction. */
 -                      data[error_byte_pos] ^= error_bit_mask;
 -              }
 +      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;
        }
  }
  
@@@ -362,83 -720,58 +546,83 @@@ static int omap_correct_data_bch(struc
                                uint8_t *read_ecc, uint8_t *calc_ecc)
  {
        struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *bch = chip->priv;
 -      uint8_t syndrome[28];
 -      uint32_t error_count = 0;
 -      uint32_t error_loc[8];
 -      uint32_t i, ecc_flag;
 -      int k, ecc_bytes, num_steps;
 -
 -      num_steps = chip->ecc.size / 512;
 -      ecc_bytes = chip->ecc.bytes / num_steps;
 -
 -      for (k = 0; k < num_steps; k++) {
 -              ecc_flag = 0;
 -              /* check if area is flashed */
 -              for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++)
 -                      if (read_ecc[i] != 0xff)
 -                              ecc_flag = 1;
 -
 -              if (ecc_flag) {
 -                      ecc_flag = 0;
 -                      /* check if any ecc error */
 -                      for (i = 0; (i < ecc_bytes) && !ecc_flag; i++)
 -                              if (calc_ecc[i] != 0)
 -                                      ecc_flag = 1;
 -              }
 -
 -              if (!ecc_flag)
 -                      return 0;
 -
 -              elm_reset();
 -              elm_config((enum bch_level)(bch->type));
 +      struct omap_nand_info *info = chip->priv;
 +      struct nand_ecc_ctrl *ecc = &chip->ecc;
 +      uint32_t error_count = 0, error_max;
 +      uint32_t error_loc[ELM_MAX_ERROR_COUNT];
 +      enum bch_level bch_type;
 +      uint32_t i, ecc_flag = 0;
 +      uint8_t count;
 +      uint32_t byte_pos, bit_pos;
 +      int err = 0;
 +
 +      /* check calculated ecc */
 +      for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
 +              if (calc_ecc[i] != 0x00)
 +                      ecc_flag = 1;
 +      }
 +      if (!ecc_flag)
 +              return 0;
 +
 +      /* check for whether its a erased-page */
 +      ecc_flag = 0;
 +      for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
 +              if (read_ecc[i] != 0xff)
 +                      ecc_flag = 1;
 +      }
 +      if (!ecc_flag)
 +              return 0;
  
 -              /*
 -               * while reading ECC result we read it in big endian.
 -               * Hence while loading to ELM we have rotate to get the right endian.
 -               */
 -              omap_rotate_ecc_bch(mtd, calc_ecc, syndrome);
 +      /*
 +       * while reading ECC result we read it in big endian.
 +       * Hence while loading to ELM we have rotate to get the right endian.
 +       */
 +      switch (info->ecc_scheme) {
 +      case OMAP_ECC_BCH8_CODE_HW:
 +              bch_type = BCH_8_BIT;
 +              omap_reverse_list(calc_ecc, ecc->bytes - 1);
 +              break;
 +      case OMAP_ECC_BCH16_CODE_HW:
 +              bch_type = BCH_16_BIT;
 +              omap_reverse_list(calc_ecc, ecc->bytes);
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +      /* use elm module to check for errors */
 +      elm_config(bch_type);
 +      err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
 +      if (err)
 +              return err;
  
 -              /* use elm module to check for errors */
 -              if (elm_check_error(syndrome, bch->nibbles, &error_count,
 -                                      error_loc) != 0) {
 -                      printf("ECC: uncorrectable.\n");
 -                      return -1;
 +      /* correct bch error */
 +      for (count = 0; count < error_count; count++) {
 +              switch (info->ecc_scheme) {
 +              case OMAP_ECC_BCH8_CODE_HW:
 +                      /* 14th byte in ECC is reserved to match ROM layout */
 +                      error_max = SECTOR_BYTES + (ecc->bytes - 1);
 +                      break;
 +              case OMAP_ECC_BCH16_CODE_HW:
 +                      error_max = SECTOR_BYTES + ecc->bytes;
 +                      break;
 +              default:
 +                      return -EINVAL;
 +              }
 +              byte_pos = error_max - (error_loc[count] / 8) - 1;
 +              bit_pos  = error_loc[count] % 8;
 +              if (byte_pos < SECTOR_BYTES) {
 +                      dat[byte_pos] ^= 1 << bit_pos;
 +                      printf("nand: bit-flip corrected @data=%d\n", byte_pos);
 +              } else if (byte_pos < error_max) {
 +                      read_ecc[byte_pos - SECTOR_BYTES] ^= 1 << bit_pos;
 +                      printf("nand: bit-flip corrected @oob=%d\n", byte_pos -
 +                                                              SECTOR_BYTES);
 +              } else {
 +                      err = -EBADMSG;
 +                      printf("nand: error: invalid bit-flip location\n");
                }
 -
 -              /* correct bch error */
 -              if (error_count > 0)
 -                      omap_fix_errors_bch(mtd, dat, error_count, error_loc);
 -              dat += 512;
 -              read_ecc += ecc_bytes;
 -              calc_ecc += ecc_bytes;
        }
 -      return 0;
 +      return (err) ? err : error_count;
  }
  
  /**
@@@ -460,24 -793,23 +644,23 @@@ static int omap_read_page_bch(struct mt
        uint8_t *ecc_calc = chip->buffers->ecccalc;
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
-       uint8_t *oob = chip->oob_poi;
+       uint8_t *oob = &chip->oob_poi[eccpos[0]];
        uint32_t data_pos;
        uint32_t oob_pos;
  
        data_pos = 0;
        /* oob area start */
-       oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
-       oob += chip->ecc.layout->eccpos[0];
+       oob_pos = (eccsize * eccsteps) + eccpos[0];
  
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
                                oob += eccbytes) {
                chip->ecc.hwctl(mtd, NAND_ECC_READ);
                /* read data */
 -              chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
 +              chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
                chip->read_buf(mtd, p, eccsize);
  
                /* read respective ecc from oob area */
 -              chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
 +              chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
                chip->read_buf(mtd, oob, eccbytes);
                /* read syndrome */
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
        }
        return 0;
  }
 -#endif /* CONFIG_AM33XX */
 +#endif /* CONFIG_NAND_OMAP_ELM */
  
  /*
   * OMAP3 BCH8 support (with BCH library)
   */
 -#ifdef CONFIG_NAND_OMAP_BCH8
 -/*
 - *  omap_calculate_ecc_bch - Read BCH ECC result
 - *
 - *  @mtd:     MTD device structure
 - *  @dat:     The pointer to data on which ecc is computed (unused here)
 - *  @ecc:     The ECC output buffer
 - */
 -static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
 -                              uint8_t *ecc)
 -{
 -      int ret = 0;
 -      size_t i;
 -      unsigned long nsectors, val1, val2, val3, val4;
 -
 -      nsectors = ((readl(&gpmc_cfg->ecc_config) >> 4) & 0x7) + 1;
 -
 -      for (i = 0; i < nsectors; i++) {
 -              /* Read hw-computed remainder */
 -              val1 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[0]);
 -              val2 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[1]);
 -              val3 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[2]);
 -              val4 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[3]);
 -
 -              /*
 -               * Add constant polynomial to remainder, in order to get an ecc
 -               * sequence of 0xFFs for a buffer filled with 0xFFs.
 -               */
 -              *ecc++ = 0xef ^ (val4 & 0xFF);
 -              *ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
 -              *ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
 -              *ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
 -              *ecc++ = 0xed ^ (val3 & 0xFF);
 -              *ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
 -              *ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
 -              *ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
 -              *ecc++ = 0x97 ^ (val2 & 0xFF);
 -              *ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
 -              *ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
 -              *ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
 -              *ecc++ = 0xb5 ^ (val1 & 0xFF);
 -      }
 -
 -      /*
 -       * Stop reading anymore ECC vals and clear old results
 -       * enable will be called if more reads are required
 -       */
 -      omap_ecc_disable(mtd);
 -
 -      return ret;
 -}
 -
 +#ifdef CONFIG_BCH
  /**
 - * omap_correct_data_bch - Decode received data and correct errors
 + * omap_correct_data_bch_sw - Decode received data and correct errors
   * @mtd: MTD device structure
   * @data: page data
   * @read_ecc: ecc read from nand flash
   * @calc_ecc: ecc read from HW ECC registers
   */
 -static int omap_correct_data_bch(struct mtd_info *mtd, u_char *data,
 +static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
                                 u_char *read_ecc, u_char *calc_ecc)
  {
        int i, count;
        /* cannot correct more than 8 errors */
        unsigned int errloc[8];
        struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *chip_priv = chip->priv;
 -      struct bch_control *bch = chip_priv->control;
 +      struct omap_nand_info *info = chip->priv;
  
 -      count = decode_bch(bch, NULL, 512, read_ecc, calc_ecc, NULL, errloc);
 +      count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
 +                                                      NULL, errloc);
        if (count > 0) {
                /* correct errors */
                for (i = 0; i < count; i++) {
                                data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
                        printf("corrected bitflip %u\n", errloc[i]);
  #ifdef DEBUG
-                       puts("read_ecc: ");
+                       printf("read_ecc: ");
                        /*
                         * BCH8 have 13 bytes of ECC; BCH4 needs adoption
                         * here!
                         */
                        for (i = 0; i < 13; i++)
                                printf("%02x ", read_ecc[i]);
-                       puts("\n");
-                       puts("calc_ecc: ");
+                       printf("\n");
+                       printf("calc_ecc: ");
                        for (i = 0; i < 13; i++)
                                printf("%02x ", calc_ecc[i]);
-                       puts("\n");
+                       printf("\n");
  #endif
                }
        } else if (count < 0) {
-               puts("ecc unrecoverable error\n");
+               printf("ecc unrecoverable error\n");
        }
        return count;
  }
  static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
  {
        struct nand_chip *chip = mtd->priv;
 -      struct nand_bch_priv *chip_priv = chip->priv;
 -      struct bch_control *bch = NULL;
 +      struct omap_nand_info *info = chip->priv;
  
 -      if (chip_priv)
 -              bch = chip_priv->control;
 +      if (info->control) {
 +              free_bch(info->control);
 +              info->control = NULL;
 +      }
 +}
 +#endif /* CONFIG_BCH */
 +
 +/**
 + * omap_select_ecc_scheme - configures driver for particular ecc-scheme
 + * @nand: NAND chip device structure
 + * @ecc_scheme: ecc scheme to configure
 + * @pagesize: number of main-area bytes per page of NAND device
 + * @oobsize: number of OOB/spare bytes per page of NAND device
 + */
 +static int omap_select_ecc_scheme(struct nand_chip *nand,
 +      enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
 +      struct omap_nand_info   *info           = nand->priv;
 +      struct nand_ecclayout   *ecclayout      = &omap_ecclayout;
 +      int eccsteps = pagesize / SECTOR_BYTES;
 +      int i;
 +
 +      switch (ecc_scheme) {
 +      case OMAP_ECC_HAM1_CODE_SW:
 +              debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
 +              /* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
 +               * initialized in nand_scan_tail(), so just set ecc.mode */
 +              info->control           = NULL;
 +              nand->ecc.mode          = NAND_ECC_SOFT;
 +              nand->ecc.layout        = NULL;
 +              nand->ecc.size          = 0;
 +              break;
  
 -      if (bch) {
 -              free_bch(bch);
 -              chip_priv->control = NULL;
 +      case OMAP_ECC_HAM1_CODE_HW:
 +              debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n");
 +              /* check ecc-scheme requirements before updating ecc info */
 +              if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
 +                      printf("nand: error: insufficient OOB: require=%d\n", (
 +                              (3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
 +                      return -EINVAL;
 +              }
 +              info->control           = NULL;
 +              /* populate ecc specific fields */
 +              memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 +              nand->ecc.mode          = NAND_ECC_HW;
 +              nand->ecc.strength      = 1;
 +              nand->ecc.size          = SECTOR_BYTES;
 +              nand->ecc.bytes         = 3;
 +              nand->ecc.hwctl         = omap_enable_hwecc;
 +              nand->ecc.correct       = omap_correct_data;
 +              nand->ecc.calculate     = omap_calculate_ecc;
 +              /* define ecc-layout */
 +              ecclayout->eccbytes     = nand->ecc.bytes * eccsteps;
 +              for (i = 0; i < ecclayout->eccbytes; i++) {
 +                      if (nand->options & NAND_BUSWIDTH_16)
 +                              ecclayout->eccpos[i] = i + 2;
 +                      else
 +                              ecclayout->eccpos[i] = i + 1;
 +              }
 +              ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
 +                                              BADBLOCK_MARKER_LENGTH;
 +              break;
 +
 +      case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 +#ifdef CONFIG_BCH
 +              debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
 +              /* check ecc-scheme requirements before updating ecc info */
 +              if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
 +                      printf("nand: error: insufficient OOB: require=%d\n", (
 +                              (13 * eccsteps) + BADBLOCK_MARKER_LENGTH));
 +                      return -EINVAL;
 +              }
 +              /* check if BCH S/W library can be used for error detection */
 +              info->control = init_bch(13, 8, 0x201b);
 +              if (!info->control) {
 +                      printf("nand: error: could not init_bch()\n");
 +                      return -ENODEV;
 +              }
 +              /* populate ecc specific fields */
 +              memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 +              nand->ecc.mode          = NAND_ECC_HW;
 +              nand->ecc.strength      = 8;
 +              nand->ecc.size          = SECTOR_BYTES;
 +              nand->ecc.bytes         = 13;
 +              nand->ecc.hwctl         = omap_enable_hwecc;
 +              nand->ecc.correct       = omap_correct_data_bch_sw;
 +              nand->ecc.calculate     = omap_calculate_ecc;
 +              /* define ecc-layout */
 +              ecclayout->eccbytes     = nand->ecc.bytes * eccsteps;
 +              ecclayout->eccpos[0]    = BADBLOCK_MARKER_LENGTH;
 +              for (i = 1; i < ecclayout->eccbytes; i++) {
 +                      if (i % nand->ecc.bytes)
 +                              ecclayout->eccpos[i] =
 +                                              ecclayout->eccpos[i - 1] + 1;
 +                      else
 +                              ecclayout->eccpos[i] =
 +                                              ecclayout->eccpos[i - 1] + 2;
 +              }
 +              ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
 +                                              BADBLOCK_MARKER_LENGTH;
 +              break;
 +#else
 +              printf("nand: error: CONFIG_BCH required for ECC\n");
 +              return -EINVAL;
 +#endif
 +
 +      case OMAP_ECC_BCH8_CODE_HW:
 +#ifdef CONFIG_NAND_OMAP_ELM
 +              debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
 +              /* check ecc-scheme requirements before updating ecc info */
 +              if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
 +                      printf("nand: error: insufficient OOB: require=%d\n", (
 +                              (14 * eccsteps) + BADBLOCK_MARKER_LENGTH));
 +                      return -EINVAL;
 +              }
 +              /* intialize ELM for ECC error detection */
 +              elm_init();
 +              info->control           = NULL;
 +              /* populate ecc specific fields */
 +              memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
 +              nand->ecc.mode          = NAND_ECC_HW;
 +              nand->ecc.strength      = 8;
 +              nand->ecc.size          = SECTOR_BYTES;
 +              nand->ecc.bytes         = 14;
 +              nand->ecc.hwctl         = omap_enable_hwecc;
 +              nand->ecc.correct       = omap_correct_data_bch;
 +              nand->ecc.calculate     = omap_calculate_ecc;
 +              nand->ecc.read_page     = omap_read_page_bch;
 +              /* define ecc-layout */
 +              ecclayout->eccbytes     = nand->ecc.bytes * eccsteps;
 +              for (i = 0; i < ecclayout->eccbytes; i++)
 +                      ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
 +                                              BADBLOCK_MARKER_LENGTH;
 +              break;
 +#else
 +              printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
 +              return -EINVAL;
 +#endif
 +
 +      case OMAP_ECC_BCH16_CODE_HW:
 +#ifdef CONFIG_NAND_OMAP_ELM
 +              debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
 +              /* check ecc-scheme requirements before updating ecc info */
 +              if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
 +                      printf("nand: error: insufficient OOB: require=%d\n", (
 +                              (26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
 +                      return -EINVAL;
 +              }
 +              /* intialize ELM for ECC error detection */
 +              elm_init();
 +              /* populate ecc specific fields */
 +              nand->ecc.mode          = NAND_ECC_HW;
 +              nand->ecc.size          = SECTOR_BYTES;
 +              nand->ecc.bytes         = 26;
 +              nand->ecc.strength      = 16;
 +              nand->ecc.hwctl         = omap_enable_hwecc;
 +              nand->ecc.correct       = omap_correct_data_bch;
 +              nand->ecc.calculate     = omap_calculate_ecc;
 +              nand->ecc.read_page     = omap_read_page_bch;
 +              /* define ecc-layout */
 +              ecclayout->eccbytes     = nand->ecc.bytes * eccsteps;
 +              for (i = 0; i < ecclayout->eccbytes; i++)
 +                      ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
 +              ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
 +                                              BADBLOCK_MARKER_LENGTH;
 +              break;
 +#else
 +              printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
 +              return -EINVAL;
 +#endif
 +      default:
 +              debug("nand: error: ecc scheme not enabled or supported\n");
 +              return -EINVAL;
        }
 +
 +      /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
 +      if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
 +              nand->ecc.layout = ecclayout;
 +
 +      info->ecc_scheme = ecc_scheme;
 +      return 0;
  }
 -#endif /* CONFIG_NAND_OMAP_BCH8 */
  
  #ifndef CONFIG_SPL_BUILD
  /*
   * @eccstrength               - the number of bits that could be corrected
   *                      (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)
   */
 -void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
 +int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
  {
        struct nand_chip *nand;
        struct mtd_info *mtd;
 +      int err = 0;
  
        if (nand_curr_device < 0 ||
            nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
            !nand_info[nand_curr_device].name) {
 -              printf("Error: Can't switch ecc, no devices available\n");
 -              return;
 +              printf("nand: error: no NAND devices found\n");
 +              return -ENODEV;
        }
  
        mtd = &nand_info[nand_curr_device];
        nand = mtd->priv;
 -
        nand->options |= NAND_OWN_BUFFERS;
 -
 -      /* Reset ecc interface */
 -      nand->ecc.mode = NAND_ECC_NONE;
 -      nand->ecc.read_page = NULL;
 -      nand->ecc.write_page = NULL;
 -      nand->ecc.read_oob = NULL;
 -      nand->ecc.write_oob = NULL;
 -      nand->ecc.hwctl = NULL;
 -      nand->ecc.correct = NULL;
 -      nand->ecc.calculate = NULL;
 -      nand->ecc.strength = eccstrength;
 -
 +      nand->options &= ~NAND_SUBPAGE_READ;
        /* Setup the ecc configurations again */
        if (hardware) {
                if (eccstrength == 1) {
 -                      nand->ecc.mode = NAND_ECC_HW;
 -                      nand->ecc.layout = &hw_nand_oob;
 -                      nand->ecc.size = 512;
 -                      nand->ecc.bytes = 3;
 -                      nand->ecc.hwctl = omap_enable_hwecc;
 -                      nand->ecc.correct = omap_correct_data;
 -                      nand->ecc.calculate = omap_calculate_ecc;
 -                      omap_hwecc_init(nand);
 -                      printf("1-bit hamming HW ECC selected\n");
 -              }
 -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
 -              else if (eccstrength == 8) {
 -                      nand->ecc.mode = NAND_ECC_HW;
 -                      nand->ecc.layout = &hw_bch8_nand_oob;
 -                      nand->ecc.size = 512;
 -#ifdef CONFIG_AM33XX
 -                      nand->ecc.bytes = 14;
 -                      nand->ecc.read_page = omap_read_page_bch;
 -#else
 -                      nand->ecc.bytes = 13;
 -#endif
 -                      nand->ecc.hwctl = omap_enable_ecc_bch;
 -                      nand->ecc.correct = omap_correct_data_bch;
 -                      nand->ecc.calculate = omap_calculate_ecc_bch;
 -                      omap_hwecc_init_bch(nand, NAND_ECC_READ);
 -                      printf("8-bit BCH HW ECC selected\n");
 +                      err = omap_select_ecc_scheme(nand,
 +                                      OMAP_ECC_HAM1_CODE_HW,
 +                                      mtd->writesize, mtd->oobsize);
 +              } else if (eccstrength == 8) {
 +                      err = omap_select_ecc_scheme(nand,
 +                                      OMAP_ECC_BCH8_CODE_HW,
 +                                      mtd->writesize, mtd->oobsize);
 +              } else {
 +                      printf("nand: error: unsupported ECC scheme\n");
 +                      return -EINVAL;
                }
 -#endif
        } else {
 -              nand->ecc.mode = NAND_ECC_SOFT;
 -              /* Use mtd default settings */
 -              nand->ecc.layout = NULL;
 -              nand->ecc.size = 0;
 -              printf("SW ECC selected\n");
 +              err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
 +                                      mtd->writesize, mtd->oobsize);
        }
  
        /* Update NAND handling after ECC mode switch */
 -      nand_scan_tail(mtd);
 -
 -      nand->options &= ~NAND_OWN_BUFFERS;
 +      if (!err)
 +              err = nand_scan_tail(mtd);
 +      return err;
  }
  #endif /* CONFIG_SPL_BUILD */
  
  int board_nand_init(struct nand_chip *nand)
  {
        int32_t gpmc_config = 0;
 -      cs = 0;
 -
 +      int cs = cs_next++;
 +      int err = 0;
        /*
         * xloader/Uboot's gpmc configuration would have configured GPMC for
         * nand type of memory. The following logic scans and latches on to the
                cs++;
        }
        if (cs >= GPMC_MAX_CS) {
 -              printf("NAND: Unable to find NAND settings in "
 +              printf("nand: error: Unable to find NAND settings in "
                        "GPMC Configuration - quitting\n");
                return -ENODEV;
        }
  
        nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
        nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
 -
 -      nand->cmd_ctrl = omap_nand_hwcontrol;
 -      nand->options = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_SUBPAGE_WRITE;
 -      /* If we are 16 bit dev, our gpmc config tells us that */
 -      if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
 -              nand->options |= NAND_BUSWIDTH_16;
 -
 +      omap_nand_info[cs].control = NULL;
 +      omap_nand_info[cs].cs = cs;
 +      nand->priv      = &omap_nand_info[cs];
 +      nand->cmd_ctrl  = omap_nand_hwcontrol;
 +      nand->options   |= NAND_NO_PADDING | NAND_CACHEPRG;
        nand->chip_delay = 100;
 +      nand->ecc.layout = &omap_ecclayout;
  
 -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
 -#ifdef CONFIG_AM33XX
 -      /* AM33xx uses the ELM */
 -      /* required in case of BCH */
 -      elm_init();
 -#else
 -      /*
 -       * Whereas other OMAP based SoC do not have the ELM, they use the BCH
 -       * SW library.
 -       */
 -      bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */);
 -      if (!bch_priv.control) {
 -              printf("Failed to initialize BCH engine\n");
 -              return -ENODEV;
 -      }
 -#endif
 -      /* BCH info that will be correct for SPL or overridden otherwise. */
 -      nand->priv = &bch_priv;
 -#endif
 -
 -      /* Default ECC mode */
 -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
 -      nand->ecc.mode = NAND_ECC_HW;
 -      nand->ecc.layout = &hw_bch8_nand_oob;
 -#ifdef CONFIG_SYS_GPMC_PREFETCH_ENABLE
 -      nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE * 4;
 -      nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES * 4;
 +      /* configure driver and controller based on NAND device bus-width */
 +      gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
 +#if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
 +      nand->options |= NAND_BUSWIDTH_16;
 +      writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
  #else
 -      nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
 -      nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
 -#endif
 -      nand->ecc.strength = 8;
 -      nand->ecc.hwctl = omap_enable_ecc_bch;
 -      nand->ecc.correct = omap_correct_data_bch;
 -      nand->ecc.calculate = omap_calculate_ecc_bch;
 -#ifdef CONFIG_AM33XX
 -      nand->ecc.read_page = omap_read_page_bch;
 +      nand->options &= ~NAND_BUSWIDTH_16;
 +      writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
  #endif
 -      omap_hwecc_init_bch(nand, NAND_ECC_READ);
 +      /* select ECC scheme */
 +#if defined(CONFIG_NAND_OMAP_ECCSCHEME)
 +      err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
 +                      CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);
  #else
 -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
 -      nand->ecc.mode = NAND_ECC_SOFT;
 -#else
 -      nand->ecc.mode = NAND_ECC_HW;
 -      nand->ecc.layout = &hw_nand_oob;
 -      nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
 -      nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
 -      nand->ecc.hwctl = omap_enable_hwecc;
 -      nand->ecc.correct = omap_correct_data;
 -      nand->ecc.calculate = omap_calculate_ecc;
 -      nand->ecc.strength = 1;
 -      omap_hwecc_init(nand);
 -#endif
 +      /* pagesize and oobsize are not required to configure sw ecc-scheme */
 +      err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
 +                      0, 0);
  #endif
 +      if (err)
 +              return err;
+ #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+       if (nand->ecc.layout) {
+               bbt_main_descr.offs = nand->ecc.layout->oobfree[0].offset;
+               bbt_main_descr.veroffs = bbt_main_descr.offs +
+                       sizeof(bbt_pattern);
+               bbt_mirror_descr.offs = nand->ecc.layout->oobfree[0].offset;
+               bbt_mirror_descr.veroffs = bbt_mirror_descr.offs +
+                       sizeof(mirror_pattern);
+       }
+       nand->bbt_options |= NAND_BBT_USE_FLASH;
+       nand->bbt_td = &bbt_main_descr;
+       nand->bbt_md = &bbt_mirror_descr;
+ #endif
  
  #ifdef CONFIG_SPL_BUILD
        if (nand->options & NAND_BUSWIDTH_16)
                nand->read_buf = nand_read_buf16;
        else
                nand->read_buf = nand_read_buf;
 -      nand->dev_ready = omap_spl_dev_ready;
 -#else
 -#ifdef CONFIG_SYS_GPMC_PREFETCH_ENABLE
 -      nand->write_buf = write_buf_pref;
 -      nand->read_buf = read_buf_pref;
 -#endif /* CONFIG_SYS_GPMC_PREFETCH_ENABLE */
 -#endif /* CONFIG_SPL_BUILD */
 +#endif
 +
 +      nand->dev_ready = omap_dev_ready;
  
        return 0;
  }
diff --combined drivers/net/Kconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,0000000000000000000000000000000000000000..c5736b0c3775e79ee5cafe8e1f083458883622ee
mode 100644,000000..100644
--- /dev/null
@@@ -1,0 -1,0 +1,33 @@@
++menuconfig NETDEVICES
++      bool "Network device support"
++      depends on NET
++
++if NETDEVICES
++
++config MII
++      bool
++
++config FEC_MXC
++      bool "Freescale FEC ethernet controller"
++      select MII
++
++config GET_FEC_MAC_ADDR_FROM_IIM
++      bool "Read FEC MAC address from fuses"
++      depends on FEC_MXC
++
++if FEC_MXC
++
++config FEC_MXC_MULTI
++      bool "Support multiple ethernet interfaces"
++      depends on MX28 || MX6
++
++config FEC_MXC_PHYADDR
++      int "FEC Ethernet PHY address"
++              default 0
++      depends on !FEC_MXC_MULTI
++
++endif
++
++source "drivers/net/phy/Kconfig"
++
++endif
diff --combined drivers/net/cpsw.c
index 52f8da67e1d9049da108238e8955ae2de3d0fce5,63f7ab473564493c6b92346e6292bfe590193762..725108d0ea392f15f7e09c178093a9eb6eb9db91
  #include <malloc.h>
  #include <net.h>
  #include <netdev.h>
- #include <cpsw.h>
  #include <asm/errno.h>
  #include <asm/io.h>
  #include <phy.h>
  #include <asm/arch/cpu.h>
  
  #define BITMASK(bits)         (BIT(bits) - 1)
  #define PHY_REG_MASK          0x1f
  #define PHY_ID_MASK           0x1f
  #define NUM_DESCS             (PKTBUFSRX * 2)
  #define PKT_MIN                       60
  #define PKT_MAX                       (1500 + 14 + 4 + 4)
  #define CLEAR_BIT             1
+ /* MAC_CONTROL register bits */
  #define GIGABITEN             BIT(7)
  #define FULLDUPLEXEN          BIT(0)
+ #define MAC_CTRL_CMD_IDLE     BIT(11)
  #define MIIEN                 BIT(15)
  
+ /* MAC_STATUS register bits */
+ #define MAC_STAT_IDLE         BIT(31)
  /* DMA Registers */
  #define CPDMA_TXCONTROL               0x004
  #define CPDMA_RXCONTROL               0x014
  #define CPDMA_SOFTRESET               0x01c
+ #define CPDMA_DMACONTROL      0x020
+ #define CPDMA_DMASTATUS               0x024
  #define CPDMA_RXFREE          0x0e0
  #define CPDMA_TXHDP_VER1      0x100
  #define CPDMA_TXHDP_VER2      0x200
  #define CPDMA_RXCP_VER1               0x160
  #define CPDMA_RXCP_VER2               0x260
  
 -#define CPDMA_RAM_ADDR                0x4a102000
 -
+ #define DMACONTROL_CMD_IDLE   BIT(3)
+ #define DMASTATUS_IDLE                BIT(31)
  /* Descriptor mode bits */
  #define CPDMA_DESC_SOP                BIT(31)
  #define CPDMA_DESC_EOP                BIT(30)
@@@ -88,8 -102,8 +100,8 @@@ struct cpsw_mdio_regs 
  #define USERACCESS_GO         BIT(31)
  #define USERACCESS_WRITE      BIT(30)
  #define USERACCESS_ACK                BIT(29)
- #define USERACCESS_READ               (0)
- #define USERACCESS_DATA               (0xffff)
+ #define USERACCESS_READ               0
+ #define USERACCESS_DATA               0xffff
        } user[0];
  };
  
@@@ -193,33 -207,34 +205,36 @@@ struct cpdma_desc 
        u32                     hw_buffer;
        u32                     hw_len;
        u32                     hw_mode;
-       /* software fields */
-       u32                     sw_buffer;
-       u32                     sw_len;
+ } __attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+ struct cpsw_desc {
+       void *sw_buffer;
+       struct cpsw_desc *next;
+       struct cpdma_desc *dma_desc;
  };
  
  struct cpdma_chan {
-       struct cpdma_desc       *head, *tail;
+       struct cpsw_desc        *head, *tail;
        void                    *hdp, *cp, *rxfree;
  };
  
- #define desc_write(desc, fld, val)    __raw_writel((u32)(val), &(desc)->fld)
- #define desc_read(desc, fld)          __raw_readl(&(desc)->fld)
- #define desc_read_ptr(desc, fld)      ((void *)__raw_readl(&(desc)->fld))
+ #define desc_write(desc, fld, val)    __raw_writel((u32)(val), &(desc)->dma_desc->fld)
+ #define desc_read(desc, fld)          __raw_readl(&(desc)->dma_desc->fld)
+ #define desc_read_ptr(desc, fld)      ((void *)__raw_readl(&(desc)->dma_desc->fld))
  
  #define chan_write(chan, fld, val)    __raw_writel((u32)(val), (chan)->fld)
  #define chan_read(chan, fld)          __raw_readl((chan)->fld)
  #define chan_read_ptr(chan, fld)      ((void *)__raw_readl((chan)->fld))
  
 +#define for_active_slave(slave, priv) \
 +      slave = (priv)->slaves + (priv)->data.active_slave; if (slave)
  #define for_each_slave(slave, priv) \
        for (slave = (priv)->slaves; slave != (priv)->slaves + \
-                               (priv)->data.slaves; slave++)
+                               (priv)->data->slaves; slave++)
  
  struct cpsw_priv {
        struct eth_device               *dev;
-       struct cpsw_platform_data       data;
+       struct cpsw_platform_data       *data;
        int                             host_port;
  
        struct cpsw_regs                *regs;
        struct cpsw_host_regs           *host_port_regs;
        void                            *ale_regs;
  
-       struct cpdma_desc               *descs;
-       struct cpdma_desc               *desc_free;
+       struct cpsw_desc                descs[NUM_DESCS];
+       struct cpsw_desc                *desc_free;
        struct cpdma_chan               rx_chan, tx_chan;
  
        struct cpsw_slave               *slaves;
        struct phy_device               *phydev;
        struct mii_dev                  *bus;
  
 -      u32                             mdio_link;
        u32                             phy_mask;
  };
  
@@@ -326,7 -342,7 +341,7 @@@ static int cpsw_ale_match_addr(struct c
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
  
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                u8 entry_addr[6];
  
                cpsw_ale_read(priv, idx, ale_entry);
@@@ -345,7 -361,7 +360,7 @@@ static int cpsw_ale_match_free(struct c
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
  
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type == ALE_TYPE_FREE)
@@@ -359,7 -375,7 +374,7 @@@ static int cpsw_ale_find_ageable(struc
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
  
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
@@@ -458,17 -474,17 +473,17 @@@ static struct cpsw_mdio_regs *mdio_regs
  /* wait until hardware is ready for another user access */
  static inline u32 wait_for_user_access(void)
  {
-       u32 reg = 0;
        int timeout = MDIO_TIMEOUT;
+       u32 reg;
  
-       while (timeout-- &&
-       ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO))
-               udelay(10);
-       if (timeout == -1) {
-               printf("wait_for_user_access Timeout\n");
-               return -ETIMEDOUT;
+       while ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO) {
+               udelay(1000);
+               if (--timeout <= 0) {
+                       printf("TIMEOUT waiting for USERACCESS_GO\n");
+                       break;
+               }
        }
        return reg;
  }
  
@@@ -477,28 -493,34 +492,34 @@@ static inline void wait_for_idle(void
  {
        int timeout = MDIO_TIMEOUT;
  
-       while (timeout-- &&
-               ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0))
-               udelay(10);
-       if (timeout == -1)
-               printf("wait_for_idle Timeout\n");
+       while ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0) {
+               if (--timeout <= 0) {
+                       printf("TIMEOUT waiting for state machine idle\n");
+                       break;
+               }
+               udelay(1000);
+       }
  }
  
  static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
                                int dev_addr, int phy_reg)
  {
 -      unsigned short data;
 +      int data;
        u32 reg;
  
        if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
                return -EINVAL;
  
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               /* promote error from previous access */
+               return -ETIME;
        reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
               (phy_id << 16));
        __raw_writel(reg, &mdio_regs->user[0].access);
        reg = wait_for_user_access();
+       if (reg & USERACCESS_GO)
+               return -ETIME;
  
        data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
        return data;
@@@ -512,11 -534,15 +533,15 @@@ static int cpsw_mdio_write(struct mii_d
        if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
                return -EINVAL;
  
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               /* promote error from previous access */
+               return -ETIME;
        reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
                   (phy_id << 16) | (data & USERACCESS_DATA));
        __raw_writel(reg, &mdio_regs->user[0].access);
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               return -ETIME;
  
        return 0;
  }
@@@ -550,9 -576,12 +575,12 @@@ static void cpsw_mdio_init(char *name, 
  /* Set a self-clearing bit in a register, and wait for it to clear */
  static inline void setbit_and_wait_for_clear32(void *addr)
  {
+       int loops = 0;
        __raw_writel(CLEAR_BIT, addr);
        while (__raw_readl(addr) & CLEAR_BIT)
-               ;
+               loops++;
+       debug("%s: reset finished after %u loops\n", __func__, loops);
  }
  
  #define mac_hi(mac)   (((mac)[0] << 0) | ((mac)[1] << 8) |    \
@@@ -566,29 -595,32 +594,32 @@@ static void cpsw_set_slave_mac(struct c
        __raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo);
  }
  
+ #define NUM_TRIES 50
  static void cpsw_slave_update_link(struct cpsw_slave *slave,
                                   struct cpsw_priv *priv, int *link)
  {
 -      struct phy_device *phy = priv->phydev;
 +      struct phy_device *phy;
        u32 mac_control = 0;
-       phy = priv->phydev;
-       if (!phy)
-               return;
-       phy_startup(phy);
-       *link = phy->link;
-       if (*link) { /* link up */
-               mac_control = priv->data.mac_control;
-               if (phy->speed == 1000)
-                       mac_control |= GIGABITEN;
-               if (phy->duplex == DUPLEX_FULL)
-                       mac_control |= FULLDUPLEXEN;
-               if (phy->speed == 100)
-                       mac_control |= MIIEN;
-       }
+       int retries = NUM_TRIES;
+       do {
+               phy_startup(phy);
+               *link = phy->link;
+               if (*link) { /* link up */
+                       mac_control = priv->data->mac_control;
+                       if (phy->speed == 1000)
+                               mac_control |= GIGABITEN;
+                       if (phy->duplex == DUPLEX_FULL)
+                               mac_control |= FULLDUPLEXEN;
+                       if (phy->speed == 100)
+                               mac_control |= MIIEN;
+               } else {
+                       udelay(10000);
+               }
+       } while (!*link && retries-- > 0);
+       debug("%s: mac_control: %08x -> %08x after %u loops\n", __func__,
+               slave->mac_control, mac_control, NUM_TRIES - retries);
  
        if (mac_control == slave->mac_control)
                return;
@@@ -610,10 -642,21 +641,10 @@@ static int cpsw_update_link(struct cpsw
        int link = 0;
        struct cpsw_slave *slave;
  
 -      for_each_slave(slave, priv)
 +      for_active_slave(slave, priv)
                cpsw_slave_update_link(slave, priv, &link);
 -      priv->mdio_link = readl(&mdio_regs->link);
 -      return link;
 -}
 -
 -static int cpsw_check_link(struct cpsw_priv *priv)
 -{
 -      u32 link;
 -
 -      link = __raw_readl(&mdio_regs->link) & priv->phy_mask;
 -      if (link && (link == priv->mdio_link))
 -              return 1;
  
 -      return cpsw_update_link(priv);
 +      return link;
  }
  
  static inline u32  cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
@@@ -628,6 -671,7 +659,7 @@@ static void cpsw_slave_init(struct cpsw
  {
        u32     slave_port;
  
+       debug("%s\n", __func__);
        setbit_and_wait_for_clear32(&slave->sliver->soft_reset);
  
        /* setup priority mapping */
  
        cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
  
 -      priv->phy_mask |= 1 << slave->data->phy_id;
 +      priv->phy_mask |= 1 << slave->data->phy_addr;
  }
  
- static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
+ static void cpdma_desc_get(struct cpsw_desc *desc)
+ {
+       invalidate_dcache_range((u32)desc->dma_desc, (u32)(&desc->dma_desc[1]));
+ }
+ static void cpdma_desc_put(struct cpsw_desc *desc)
+ {
+       flush_dcache_range((u32)desc->dma_desc, (u32)(&desc->dma_desc[1]));
+ }
+ static struct cpsw_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
  {
-       struct cpdma_desc *desc = priv->desc_free;
+       struct cpsw_desc *desc = priv->desc_free;
  
-       if (desc)
-               priv->desc_free = desc_read_ptr(desc, hw_next);
+       if (desc) {
+               cpdma_desc_get(desc);
+               priv->desc_free = desc->next;
+       }
        return desc;
  }
  
- static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
+ static void cpdma_desc_free(struct cpsw_priv *priv, struct cpsw_desc *desc)
  {
        if (desc) {
-               desc_write(desc, hw_next, priv->desc_free);
+               desc_write(desc, hw_next, priv->desc_free->dma_desc);
+               cpdma_desc_put(desc);
+               desc->next = priv->desc_free;
                priv->desc_free = desc;
        }
  }
  static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
                        void *buffer, int len)
  {
-       struct cpdma_desc *desc, *prev;
+       struct cpsw_desc *desc, *prev;
        u32 mode;
  
+       if (!buffer) {
+               printf("ERROR: %s() NULL buffer\n", __func__);
+               return -EINVAL;
+       }
+       flush_dcache_range((u32)buffer, (u32)buffer + len);
        desc = cpdma_desc_alloc(priv);
        if (!desc)
                return -ENOMEM;
  
+       debug("%s@%d: %cX desc %p DMA %p\n", __func__, __LINE__,
+               chan == &priv->rx_chan ? 'R' : 'T', desc, desc->dma_desc);
        if (len < PKT_MIN)
                len = PKT_MIN;
  
        mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
  
+       desc->next = NULL;
        desc_write(desc, hw_next,   0);
        desc_write(desc, hw_buffer, buffer);
        desc_write(desc, hw_len,    len);
        desc_write(desc, hw_mode,   mode | len);
-       desc_write(desc, sw_buffer, buffer);
-       desc_write(desc, sw_len,    len);
  
+       desc->sw_buffer = buffer;
+       cpdma_desc_put(desc);
        if (!chan->head) {
                /* simple case - first packet enqueued */
                chan->head = desc;
                chan->tail = desc;
-               chan_write(chan, hdp, desc);
+               chan_write(chan, hdp, desc->dma_desc);
                goto done;
        }
  
        /* not the first packet - enqueue at the tail */
        prev = chan->tail;
-       desc_write(prev, hw_next, desc);
+       prev->next = desc;
+       cpdma_desc_get(prev);
+       desc_write(prev, hw_next, desc->dma_desc);
+       cpdma_desc_put(prev);
        chan->tail = desc;
  
        /* next check if EOQ has been triggered already */
        if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ)
-               chan_write(chan, hdp, desc);
+               chan_write(chan, hdp, desc->dma_desc);
  
  done:
        if (chan->rxfree)
                chan_write(chan, rxfree, 1);
+       debug("%s@%d\n", __func__, __LINE__);
        return 0;
  }
  
  static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
                         void **buffer, int *len)
  {
-       struct cpdma_desc *desc = chan->head;
+       struct cpsw_desc *desc = chan->head;
        u32 status;
  
        if (!desc)
                return -ENOENT;
  
+       cpdma_desc_get(desc);
        status = desc_read(desc, hw_mode);
+       if (status & CPDMA_DESC_OWNER)
+               return -EBUSY;
  
        if (len)
                *len = status & 0x7ff;
  
        if (buffer)
-               *buffer = desc_read_ptr(desc, sw_buffer);
-       if (status & CPDMA_DESC_OWNER) {
-               if (chan_read(chan, hdp) == 0) {
-                       if (desc_read(desc, hw_mode) & CPDMA_DESC_OWNER)
-                               chan_write(chan, hdp, desc);
-               }
-               return -EBUSY;
-       }
+               *buffer = desc->sw_buffer;
+       debug("%s@%d: buffer=%p\n", __func__, __LINE__, desc->sw_buffer);
  
-       chan->head = desc_read_ptr(desc, hw_next);
-       chan_write(chan, cp, desc);
+       chan->head = desc->next;
+       chan_write(chan, cp, desc->dma_desc);
  
        cpdma_desc_free(priv, desc);
        return 0;
@@@ -750,6 -821,7 +809,7 @@@ static int cpsw_init(struct eth_device 
        struct cpsw_slave       *slave;
        int i, ret;
  
+       debug("%s\n", __func__);
        /* soft reset the controller and initialize priv */
        setbit_and_wait_for_clear32(&priv->regs->soft_reset);
  
  
        /* enable statistics collection only on the host port */
        __raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en);
 +      __raw_writel(0x7, &priv->regs->stat_port_en);
  
        cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
  
                           ALE_SECURE);
        cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port);
  
 -      for_each_slave(slave, priv)
 +      for_active_slave(slave, priv)
                cpsw_slave_init(slave, priv);
  
        cpsw_update_link(priv);
  
        /* init descriptor pool */
        for (i = 0; i < NUM_DESCS; i++) {
+               struct cpsw_desc *next_desc = (i < (NUM_DESCS - 1)) ?
+                       &priv->descs[i + 1] : NULL;
+               priv->descs[i].next = next_desc;
                desc_write(&priv->descs[i], hw_next,
-                          (i == (NUM_DESCS - 1)) ? 0 : &priv->descs[i+1]);
+                       next_desc ? next_desc->dma_desc : 0);
+               cpdma_desc_put(&priv->descs[i]);
        }
        priv->desc_free = &priv->descs[0];
  
        /* initialize channels */
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
                memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
-               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
-               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
-               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
+               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
+               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
  
                memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
-               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER2;
-               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER2;
+               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER2;
+               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER2;
        } else {
                memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
-               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER1;
-               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER1;
-               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER1;
+               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER1;
+               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
  
                memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
-               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER1;
-               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER1;
+               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER1;
+               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER1;
        }
  
        /* clear dma state */
        setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
  
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
-               for (i = 0; i < priv->data.channels; i++) {
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4
-                                       * i);
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
+               for (i = 0; i < priv->data->channels; i++) {
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4 * i);
                }
        } else {
-               for (i = 0; i < priv->data.channels; i++) {
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4
-                                       * i);
+               for (i = 0; i < priv->data->channels; i++) {
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4 * i);
  
                }
        }
                }
        }
  
-       return 0;
+       return ret;
  }
  
  static void cpsw_halt(struct eth_device *dev)
  {
        struct cpsw_priv        *priv = dev->priv;
+       struct cpsw_slave       *slave;
+       int idle = 0;
+       int timeout = 1000000;
+       __raw_writel(DMACONTROL_CMD_IDLE, priv->dma_regs + CPDMA_DMACONTROL);
+       while (!(__raw_readl(priv->dma_regs + CPDMA_DMASTATUS) &
+                       DMASTATUS_IDLE) && (--timeout >= 0))
+               udelay(1);
+       timeout = 1000000;
+       while (!idle) {
+               idle = 1;
+               for_each_slave(slave, priv) {
+                       if (!(__raw_readl(&slave->sliver->mac_status) &
+                                       MAC_STAT_IDLE)) {
+                               idle = 0;
+                               break;
+                       }
+               }
+               if (idle || --timeout < 0)
+                       break;
+               udelay(1);
+       }
+       if (!idle)
+               printf("CPSW: Aborting DMA transfers; packets may be lost\n");
  
        writel(0, priv->dma_regs + CPDMA_TXCONTROL);
        writel(0, priv->dma_regs + CPDMA_RXCONTROL);
        /* clear dma state */
        setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
  
-       priv->data.control(0);
+       debug("%s\n", __func__);
+       priv->data->control(0);
  }
  
  static int cpsw_send(struct eth_device *dev, void *packet, int length)
  {
-       struct cpsw_priv        *priv = dev->priv;
+       struct cpsw_priv *priv = dev->priv;
        void *buffer;
        int len;
-       int timeout = CPDMA_TIMEOUT;
  
-       flush_dcache_range((unsigned long)packet,
-                          (unsigned long)packet + length);
 -      if (!priv->data->mac_control && !cpsw_check_link(priv)) {
 -              printf("%s: Cannot send packet; link is down\n", __func__);
 -              return -EIO;
 -      }
  
        /* first reap completed packets */
-       while (timeout-- &&
-               (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0))
-               ;
-       if (timeout == -1) {
-               printf("cpdma_process timeout\n");
-               return -ETIMEDOUT;
-       }
+       while (cpdma_process(priv, &priv->tx_chan, &buffer, &len) == 0)
+               /* NOP */;
  
        return cpdma_submit(priv, &priv->tx_chan, packet, length);
  }
@@@ -901,11 -988,14 +973,14 @@@ static int cpsw_recv(struct eth_device 
        void *buffer;
        int len;
  
-       while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
-               invalidate_dcache_range((unsigned long)buffer,
-                                       (unsigned long)buffer + PKTSIZE_ALIGN);
-               NetReceive(buffer, len);
-               cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+       while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) == 0) {
+               if (buffer) {
+                       NetReceive(buffer, len);
+                       cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+               } else {
+                       printf("NULL buffer returned from cpdma_process\n");
+                       return -EIO;
+               }
        }
  
        return 0;
@@@ -915,7 -1005,10 +990,10 @@@ static void cpsw_slave_setup(struct cps
                            struct cpsw_priv *priv)
  {
        void                    *regs = priv->regs;
-       struct cpsw_slave_data  *data = priv->data.slave_data + slave_num;
+       struct cpsw_slave_data  *data = priv->data->slave_data + slave_num;
+       debug("%s@%d: slave[%d] %p\n", __func__, __LINE__,
+               slave_num, slave);
        slave->slave_num = slave_num;
        slave->data     = data;
        slave->regs     = regs + data->slave_reg_ofs;
@@@ -926,31 -1019,54 +1004,53 @@@ static int cpsw_phy_init(struct eth_dev
  {
        struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv;
        struct phy_device *phydev;
 -      u32 supported = (SUPPORTED_10baseT_Half |
 -                      SUPPORTED_10baseT_Full |
 -                      SUPPORTED_100baseT_Half |
 -                      SUPPORTED_100baseT_Full |
 -                      SUPPORTED_1000baseT_Full);
 +      u32 supported = PHY_GBIT_FEATURES;
  
-       phydev = phy_connect(priv->bus,
-                       slave->data->phy_addr,
-                       dev,
-                       slave->data->phy_if);
+       if (slave->data->phy_id < 0) {
+               u32 phy_addr;
+               for (phy_addr = 0; phy_addr < 32; phy_addr++) {
+                       debug("Trying to connect to PHY @ addr %02x\n",
+                               phy_addr);
+                       phydev = phy_connect(priv->bus, phy_addr,
+                                       dev, slave->data->phy_if);
+                       if (phydev)
+                               break;
+               }
+       } else {
+               phydev = phy_connect(priv->bus,
+                               slave->data->phy_id,
+                               dev,
+                               slave->data->phy_if);
+       }
+       if (!phydev) {
+               printf("Failed to connect to PHY\n");
+               return -EINVAL;
+       }
  
 +      if (!phydev)
 +              return -1;
 +
        phydev->supported &= supported;
        phydev->advertising = phydev->supported;
  
        priv->phydev = phydev;
        phy_config(phydev);
  
-       return 1;
+       return 0;
  }
  
  int cpsw_register(struct cpsw_platform_data *data)
  {
+       int ret = 1;
        struct cpsw_priv        *priv;
        struct cpsw_slave       *slave;
        void                    *regs = (void *)data->cpsw_base;
        struct eth_device       *dev;
+       int i;
+       int idx = 0;
+       debug("%s@%d\n", __func__, __LINE__);
  
        dev = calloc(sizeof(*dev), 1);
        if (!dev)
                return -ENOMEM;
        }
  
-       priv->data = *data;
+       priv->data = data;
        priv->dev = dev;
  
-       priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
+       priv->slaves = calloc(sizeof(struct cpsw_slave), data->slaves);
        if (!priv->slaves) {
                free(dev);
                free(priv);
                return -ENOMEM;
        }
  
 -      for (i = 0; i < NUM_DESCS; i++) {
 -              priv->descs[i].dma_desc = memalign(CONFIG_SYS_CACHELINE_SIZE,
 -                              sizeof(struct cpsw_desc) * NUM_DESCS);
 -              if (!priv->descs[i].dma_desc) {
 -                      while (--i >= 0) {
 -                              free(priv->descs[i].dma_desc);
 -                      }
 -                      free(priv->slaves);
 -                      free(priv);
 -                      free(dev);
 -                      return -ENOMEM;
 -              }
 -              debug("DMA desc[%d] allocated @ %p desc_size %u\n",
 -                      i, priv->descs[i].dma_desc,
 -                      sizeof(*priv->descs[i].dma_desc));
 -      }
 -
        priv->host_port         = data->host_port_num;
        priv->regs              = regs;
        priv->host_port_regs    = regs + data->host_port_reg_ofs;
        priv->dma_regs          = regs + data->cpdma_reg_ofs;
        priv->ale_regs          = regs + data->ale_reg_ofs;
 +      priv->descs             = (void *)regs + data->bd_ram_ofs;
  
-       int idx = 0;
        for_each_slave(slave, priv) {
                cpsw_slave_setup(slave, idx, priv);
                idx = idx + 1;
  
        cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
        priv->bus = miiphy_get_dev_by_name(dev->name);
-       for_active_slave(slave, priv)
-               cpsw_phy_init(dev, slave);
-       return 1;
 -      for_each_slave(slave, priv) {
++      for_active_slave(slave, priv) {
+               ret = cpsw_phy_init(dev, slave);
+               if (ret < 0)
+                       break;
+       }
+       return ret;
  }
diff --combined drivers/net/fec_mxc.c
index b57247032fa85aaa65ec47c9fcf7668a4cd567df,720813687b3d715408b8fd863e2946294155a6c6..63f03e6202fed61f3229837541eb505104888d9a
  #include <common.h>
  #include <malloc.h>
  #include <net.h>
 +#include <netdev.h>
  #include <miiphy.h>
- #include "fec_mxc.h"
  
+ #include <asm/arch/sys_proto.h>
  #include <asm/arch/clock.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/io.h>
  #include <asm/errno.h>
  #include <linux/compiler.h>
  
+ #include "fec_mxc.h"
  DECLARE_GLOBAL_DATA_PTR;
  
  /*
   */
  #define FEC_XFER_TIMEOUT      5000
  
 +/*
 + * The standard 32-byte DMA alignment does not work on mx6solox, which requires
 + * 64-byte alignment in the DMA RX FEC buffer.
 + * Introduce the FEC_DMA_RX_MINALIGN which can cover mx6solox needs and also
 + * satisfies the alignment on other SoCs (32-bytes)
 + */
 +#define FEC_DMA_RX_MINALIGN   64
 +
  #ifndef CONFIG_MII
  #error "CONFIG_MII has to be defined!"
  #endif
@@@ -74,6 -67,8 +76,8 @@@ struct nbuf 
        uint8_t head[16];       /**< MAC header(6 + 6 + 2) + 2(aligned) */
  };
  
+ static int rx_idx;
  #ifdef CONFIG_FEC_MXC_SWAP_PACKET
  static void swap_packet(uint32_t *packet, int length)
  {
@@@ -92,7 -87,7 +96,7 @@@ static int fec_mdio_read(struct etherne
  {
        uint32_t reg;           /* convenient holder for the PHY register */
        uint32_t phy;           /* convenient holder for the PHY */
-       uint32_t start;
+       ulong start;
        int val;
  
        /*
        start = get_timer(0);
        while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
                if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+                       if (readl(&eth->ievent) & FEC_IEVENT_MII)
+                               break;
                        printf("Read MDIO failed...\n");
                        return -1;
                }
         * it's now safe to read the PHY's register
         */
        val = (unsigned short)readl(&eth->mii_data);
-       debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+       debug("%s: phy: %02x reg:%02x val:%#06x\n", __func__, phyAddr,
                        regAddr, val);
        return val;
  }
@@@ -137,12 -134,8 +143,12 @@@ static void fec_mii_setspeed(struct eth
         * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
         * and do not drop the Preamble.
         */
 -      writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
 -                      &eth->mii_speed);
 +      register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000);
 +#ifdef FEC_QUIRK_ENET_MAC
 +      speed--;
 +#endif
 +      speed <<= 1;
 +      writel(speed, &eth->mii_speed);
        debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
  }
  
@@@ -151,7 -144,7 +157,7 @@@ static int fec_mdio_write(struct ethern
  {
        uint32_t reg;           /* convenient holder for the PHY register */
        uint32_t phy;           /* convenient holder for the PHY */
-       uint32_t start;
+       ulong start;
  
        reg = regAddr << FEC_MII_DATA_RA_SHIFT;
        phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
        start = get_timer(0);
        while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
                if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+                       if (readl(&eth->ievent) & FEC_IEVENT_MII)
+                               break;
                        printf("Write MDIO failed...\n");
                        return -1;
                }
         * clear MII interrupt bit
         */
        writel(FEC_IEVENT_MII, &eth->ievent);
-       debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+       debug("%s: phy: %02x reg:%02x val:%#06x\n", __func__, phyAddr,
                        regAddr, data);
  
        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);
  }
@@@ -255,26 -249,22 +263,22 @@@ static int miiphy_wait_aneg(struct eth_
  }
  #endif
  
- static int fec_rx_task_enable(struct fec_priv *fec)
+ static inline void fec_rx_task_enable(struct fec_priv *fec)
  {
-       writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
-       return 0;
+       writel(1 << 24, &fec->eth->r_des_active);
  }
  
- static int fec_rx_task_disable(struct fec_priv *fec)
+ static inline void fec_rx_task_disable(struct fec_priv *fec)
  {
-       return 0;
  }
  
- static int fec_tx_task_enable(struct fec_priv *fec)
+ static inline void fec_tx_task_enable(struct fec_priv *fec)
  {
-       writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
-       return 0;
+       writel(1 << 24, &fec->eth->x_des_active);
  }
  
- static int fec_tx_task_disable(struct fec_priv *fec)
+ static inline void fec_tx_task_disable(struct fec_priv *fec)
  {
-       return 0;
  }
  
  /**
   * @param[in] dsize desired size of each receive buffer
   * @return 0 on success
   *
 - * For this task we need additional memory for the data buffers. And each
 - * data buffer requires some alignment. Thy must be aligned to a specific
 - * boundary each.
 + * Init all RX descriptors to default values.
   */
 -static int fec_rbd_init(struct fec_priv *fec, int count, int dsize)
 +static void fec_rbd_init(struct fec_priv *fec, int count, int dsize)
  {
        uint32_t size;
 +      uint8_t *data;
        int i;
  
        /*
 -       * Allocate memory for the buffers. This allocation respects the
 -       * alignment
 +       * Reload the RX descriptors with default values and wipe
 +       * the RX buffers.
         */
        size = roundup(dsize, ARCH_DMA_MINALIGN);
        for (i = 0; i < count; i++) {
 -              uint32_t data_ptr = readl(&fec->rbd_base[i].data_pointer);
 -              if (data_ptr == 0) {
 -                      uint8_t *data = memalign(ARCH_DMA_MINALIGN,
 -                                               size);
 -                      if (!data) {
 -                              printf("%s: error allocating rxbuf %d\n",
 -                                     __func__, i);
 -                              goto err;
 -                      }
 -                      writel((uint32_t)data, &fec->rbd_base[i].data_pointer);
 -              } /* needs allocation */
 -              writew(FEC_RBD_EMPTY, &fec->rbd_base[i].status);
 -              writew(0, &fec->rbd_base[i].data_length);
 +              data = (uint8_t *)fec->rbd_base[i].data_pointer;
 +              memset(data, 0, dsize);
 +              flush_dcache_range((uint32_t)data, (uint32_t)data + size);
 +
 +              fec->rbd_base[i].status = FEC_RBD_EMPTY;
 +              fec->rbd_base[i].data_length = 0;
        }
  
        /* Mark the last RBD to close the ring. */
 -      writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &fec->rbd_base[i - 1].status);
 +      fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
        fec->rbd_index = 0;
  
 -      return 0;
 -
 -err:
 -      for (; i >= 0; i--) {
 -              uint32_t data_ptr = readl(&fec->rbd_base[i].data_pointer);
 -              free((void *)data_ptr);
 -      }
 -
 -      return -ENOMEM;
 +      flush_dcache_range((unsigned)fec->rbd_base,
 +                         (unsigned)fec->rbd_base + size);
  }
  
  /**
@@@ -331,10 -336,8 +335,10 @@@ static void fec_tbd_init(struct fec_pri
        unsigned addr = (unsigned)fec->tbd_base;
        unsigned size = roundup(2 * sizeof(struct fec_bd),
                                ARCH_DMA_MINALIGN);
 -      writew(0x0000, &fec->tbd_base[0].status);
 -      writew(FEC_TBD_WRAP, &fec->tbd_base[1].status);
 +
 +      memset(fec->tbd_base, 0, size);
 +      fec->tbd_base[0].status = 0;
 +      fec->tbd_base[1].status = FEC_TBD_WRAP;
        fec->tbd_index = 0;
        flush_dcache_range(addr, addr + size);
  }
@@@ -420,7 -423,7 +424,7 @@@ static void fec_reg_setup(struct fec_pr
   */
  static int fec_open(struct eth_device *edev)
  {
-       struct fec_priv *fec = (struct fec_priv *)edev->priv;
+       struct fec_priv *fec = edev->priv;
        int speed;
        uint32_t addr, size;
        int i;
         */
        writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
                &fec->eth->ecntrl);
 -#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
 +#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
        udelay(100);
        /*
         * setup the MII gasket for RMII mode
        {
                u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
                u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
                if (speed == _1000BASET)
                        ecr |= FEC_ECNTRL_SPEED;
                else if (speed != _100BASET)
                writel(ecr, &fec->eth->ecntrl);
                writel(rcr, &fec->eth->r_cntrl);
        }
+ #elif defined(CONFIG_MX28)
+       {
+               u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
+               if (speed == _10BASET)
+                       rcr |= FEC_RCNTRL_RMII_10T;
+               writel(rcr, &fec->eth->r_cntrl);
+       }
  #endif
        debug("%s:Speed=%i\n", __func__, speed);
  
         */
        fec_rx_task_enable(fec);
  
      udelay(100000);
//    udelay(100000);
        return 0;
  }
  
  static int fec_init(struct eth_device *dev, bd_t* bd)
  {
-       struct fec_priv *fec = (struct fec_priv *)dev->priv;
-       uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
+       struct fec_priv *fec = dev->priv;
+       uint32_t *mib_ptr = (uint32_t *)&fec->eth->rmon_t_drop;
 -      uint32_t size;
 -      int i, ret;
 +      int i;
  
        /* Initialize MAC address */
        fec_set_hwaddr(dev);
  
        /*
 -       * Allocate transmit descriptors, there are two in total. This
 -       * allocation respects cache alignment.
 +       * Setup transmit descriptors, there are two in total.
         */
 -      if (!fec->tbd_base) {
 -              size = roundup(2 * sizeof(struct fec_bd),
 -                              ARCH_DMA_MINALIGN);
 -              fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
 -              if (!fec->tbd_base) {
 -                      ret = -ENOMEM;
 -                      goto err1;
 -              }
 -              memset(fec->tbd_base, 0, size);
 -              fec_tbd_init(fec);
 -      }
 +      fec_tbd_init(fec);
  
 -      /*
 -       * Allocate receive descriptors. This allocation respects cache
 -       * alignment.
 -       */
 -      if (!fec->rbd_base) {
 -              size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
 -                              ARCH_DMA_MINALIGN);
 -              fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
 -              if (!fec->rbd_base) {
 -                      ret = -ENOMEM;
 -                      goto err2;
 -              }
 -              memset(fec->rbd_base, 0, size);
 -              /*
 -               * Initialize RxBD ring
 -               */
 -              if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
 -                      ret = -ENOMEM;
 -                      goto err3;
 -              }
 -              flush_dcache_range((unsigned)fec->rbd_base,
 -                                 (unsigned)fec->rbd_base + size);
 -      }
 +      /* Setup receive descriptors. */
 +      fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
  
        fec_reg_setup(fec);
  
  
  
        /* clear MIB RAM */
-       for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
-               writel(0, i);
+       for (i = 0; i <= 0xfc >> 2; i++)
+               writel(0, &mib_ptr[i]);
  
        /* FIFO receive start register */
        writel(0x520, &fec->eth->r_fstart);
  #endif
        fec_open(dev);
        return 0;
 -
 -err3:
 -      free(fec->rbd_base);
 -err2:
 -      free(fec->tbd_base);
 -err1:
 -      return ret;
  }
  
  /**
  static void fec_halt(struct eth_device *dev)
  {
        struct fec_priv *fec = (struct fec_priv *)dev->priv;
-       int counter = 0xffff;
+       int counter = 1000;
  
        /*
         * issue graceful stop command to the FEC transmitter if necessary
         * wait for graceful stop to register
         */
        while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
-               udelay(1);
+               udelay(100);
  
        /*
         * Disable SmartDMA tasks
@@@ -636,7 -688,7 +649,7 @@@ static int fec_send(struct eth_device *
         * This routine transmits one frame.  This routine only accepts
         * 6-byte Ethernet addresses.
         */
-       struct fec_priv *fec = (struct fec_priv *)dev->priv;
+       struct fec_priv *fec = dev->priv;
  
        /*
         * Check for valid length of data.
        flush_dcache_range(addr, end);
  
        writew(length, &fec->tbd_base[fec->tbd_index].data_length);
-       writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
+       writel((unsigned long)packet,
+               &fec->tbd_base[fec->tbd_index].data_pointer);
  
        /*
         * update BD's status now
         * This block:
         * - is always the last in a chain (means no chain)
-        * - should transmitt the CRC
+        * - should transmit the CRC
         * - might be the last BD in the list, so the address counter should
         *   wrap (-> keep the WRAP flag)
         */
                        break;
        }
  
 -      if (!timeout)
 +      if (!timeout) {
                ret = -EINVAL;
 +              goto out;
 +      }
  
 -      invalidate_dcache_range(addr, addr + size);
 -      if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
 +      /*
 +       * The TDAR bit is cleared when the descriptors are all out from TX
 +       * but on mx6solox we noticed that the READY bit is still not cleared
 +       * right after TDAR.
 +       * These are two distinct signals, and in IC simulation, we found that
 +       * TDAR always gets cleared prior than the READY bit of last BD becomes
 +       * cleared.
 +       * In mx6solox, we use a later version of FEC IP. It looks like that
 +       * this intrinsic behaviour of TDAR bit has changed in this newer FEC
 +       * version.
 +       *
 +       * Fix this by polling the READY bit of BD after the TDAR polling,
 +       * which covers the mx6solox case and does not harm the other SoCs.
 +       */
 +      timeout = FEC_XFER_TIMEOUT;
 +      while (--timeout) {
 +              invalidate_dcache_range(addr, addr + size);
 +              if (!(readw(&fec->tbd_base[fec->tbd_index].status) &
 +                  FEC_TBD_READY))
 +                      break;
 +      }
 +
 +      if (!timeout)
                ret = -EINVAL;
  
 +out:
        debug("fec_send: status 0x%x index %d ret %i\n",
                        readw(&fec->tbd_base[fec->tbd_index].status),
                        fec->tbd_index, ret);
@@@ -779,14 -808,16 +793,16 @@@ static int fec_recv(struct eth_device *
        uint16_t bd_status;
        uint32_t addr, size, end;
        int i;
-       ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
  
        /*
         * Check if any critical events have happened
         */
        ievent = readl(&fec->eth->ievent);
-       writel(ievent, &fec->eth->ievent);
-       debug("fec_recv: ievent 0x%lx\n", ievent);
+       if (ievent)
+               writel(ievent, &fec->eth->ievent);
+       if (ievent)
+               debug("fec_recv: ievent 0x%lx\n", ievent);
        if (ievent & FEC_IEVENT_BABR) {
                fec_halt(dev);
                fec_init(dev, fec->bd);
        invalidate_dcache_range(addr, addr + size);
  
        bd_status = readw(&rbd->status);
-       debug("fec_recv: status 0x%x\n", bd_status);
        if (!(bd_status & FEC_RBD_EMPTY)) {
+               debug("fec_recv: status 0x%04x len %u\n", bd_status,
+                       readw(&rbd->data_length) - 4);
                if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
                        ((readw(&rbd->data_length) - 4) > 14)) {
                        /*
                         */
                        frame = (struct nbuf *)readl(&rbd->data_pointer);
                        frame_length = readw(&rbd->data_length) - 4;
                        /*
                         * Invalidate data cache over the buffer
                         */
  #ifdef CONFIG_FEC_MXC_SWAP_PACKET
                        swap_packet((uint32_t *)frame->data, frame_length);
  #endif
-                       memcpy(buff, frame->data, frame_length);
-                       NetReceive(buff, frame_length);
+                       memcpy((void *)NetRxPackets[rx_idx], frame->data, frame_length);
+                       NetReceive(NetRxPackets[rx_idx], frame_length);
+                       rx_idx = (rx_idx + 1) % PKTBUFSRX;
                        len = frame_length;
                } else {
                        if (bd_status & FEC_RBD_ERR)
  
                fec_rx_task_enable(fec);
                fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
+               debug("fec_recv: stop\n");
        }
-       debug("fec_recv: stop\n");
  
        return len;
  }
@@@ -892,74 -925,6 +910,74 @@@ static void fec_set_dev_name(char *dest
        sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id);
  }
  
 +static int fec_alloc_descs(struct fec_priv *fec)
 +{
 +      unsigned int size;
 +      int i;
 +      uint8_t *data;
 +
 +      /* Allocate TX descriptors. */
 +      size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
 +      fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
 +      if (!fec->tbd_base)
 +              goto err_tx;
 +
 +      /* Allocate RX descriptors. */
 +      size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
 +      fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
 +      if (!fec->rbd_base)
 +              goto err_rx;
 +
 +      memset(fec->rbd_base, 0, size);
 +
 +      /* Allocate RX buffers. */
 +
 +      /* Maximum RX buffer size. */
 +      size = roundup(FEC_MAX_PKT_SIZE, FEC_DMA_RX_MINALIGN);
 +      for (i = 0; i < FEC_RBD_NUM; i++) {
 +              data = memalign(FEC_DMA_RX_MINALIGN, size);
 +              if (!data) {
 +                      printf("%s: error allocating rxbuf %d\n", __func__, i);
 +                      goto err_ring;
 +              }
 +
 +              memset(data, 0, size);
 +
 +              fec->rbd_base[i].data_pointer = (uint32_t)data;
 +              fec->rbd_base[i].status = FEC_RBD_EMPTY;
 +              fec->rbd_base[i].data_length = 0;
 +              /* Flush the buffer to memory. */
 +              flush_dcache_range((uint32_t)data, (uint32_t)data + size);
 +      }
 +
 +      /* Mark the last RBD to close the ring. */
 +      fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
 +
 +      fec->rbd_index = 0;
 +      fec->tbd_index = 0;
 +
 +      return 0;
 +
 +err_ring:
 +      for (; i >= 0; i--)
 +              free((void *)fec->rbd_base[i].data_pointer);
 +      free(fec->rbd_base);
 +err_rx:
 +      free(fec->tbd_base);
 +err_tx:
 +      return -ENOMEM;
 +}
 +
 +static void fec_free_descs(struct fec_priv *fec)
 +{
 +      int i;
 +
 +      for (i = 0; i < FEC_RBD_NUM; i++)
 +              free((void *)fec->rbd_base[i].data_pointer);
 +      free(fec->rbd_base);
 +      free(fec->tbd_base);
 +}
 +
  #ifdef CONFIG_PHYLIB
  int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
                struct mii_dev *bus, struct phy_device *phydev)
@@@ -975,27 -940,20 +993,24 @@@ static int fec_probe(bd_t *bd, int dev_
        int ret = 0;
  
        /* create and fill edev struct */
-       edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+       edev = calloc(sizeof(struct eth_device), 1);
        if (!edev) {
                puts("fec_mxc: not enough malloc memory for eth_device\n");
                ret = -ENOMEM;
                goto err1;
        }
  
-       fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
+       fec = calloc(sizeof(struct fec_priv), 1);
        if (!fec) {
                puts("fec_mxc: not enough malloc memory for fec_priv\n");
                ret = -ENOMEM;
                goto err2;
        }
  
-       memset(edev, 0, sizeof(*edev));
-       memset(fec, 0, sizeof(*fec));
 +      ret = fec_alloc_descs(fec);
 +      if (ret)
 +              goto err3;
 +
        edev->priv = fec;
        edev->init = fec_init;
        edev->send = fec_send;
        while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
                if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
                        printf("FEC MXC: Timeout reseting chip\n");
 -                      goto err3;
 +                      goto err4;
                }
                udelay(10);
        }
        eth_register(edev);
  
        if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
-               debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
+               if (dev_id < 0)
+                       debug("got MAC address from fuse: %pM\n", ethaddr);
+               else
+                       debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
                memcpy(edev->enetaddr, ethaddr, 6);
 +              if (!getenv("ethaddr"))
 +                      eth_setenv_enetaddr("ethaddr", ethaddr);
        }
        return ret;
 +err4:
 +      fec_free_descs(fec);
  err3:
        free(fec);
  err2:
diff --combined drivers/net/fec_mxc.h
index 0717cc6c3105c087b78fc3fc1bc63e9caced014f,7cfef86c7b91dff083dd4b41c5bf71a9747f832c..44170174cf422c218fd01c7a374a755f9e47180a
@@@ -18,8 -18,6 +18,6 @@@
  #ifndef __FEC_MXC_H
  #define __FEC_MXC_H
  
- void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
  /**
   * Layout description of the FEC
   */
@@@ -135,7 -133,7 +133,7 @@@ struct ethernet_regs 
  
        uint32_t res14[7];              /* MBAR_ETH + 0x2E4-2FC */
  
 -#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
 +#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
        uint16_t miigsk_cfgr;           /* MBAR_ETH + 0x300 */
        uint16_t res15[3];              /* MBAR_ETH + 0x302-306 */
        uint16_t miigsk_enr;            /* MBAR_ETH + 0x308 */
  #define FEC_X_DES_ACTIVE_TDAR         0x01000000
  #define FEC_R_DES_ACTIVE_RDAR         0x01000000
  
 -#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
 +#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
  /* defines for MIIGSK */
  /* RMII frequency control: 0=50MHz, 1=5MHz */
  #define MIIGSK_CFGR_FRCONT            (1 << 6)
diff --combined drivers/net/phy/Kconfig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c72785cce8e0b5badefa711f2e36ff38e290db70
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++config PHYLIB
++      bool "Generic PHY support"
++
++config PHY_SMSC
++      bool "SMSC PHY support"
diff --combined drivers/net/phy/phy.c
index 5b04c85939040c27b832194a32f171686d6b88f6,58ba5c2c2c74446f6d5fe47f0fe7b5c452341612..a8ef661b3edb2ce897f8d6b91fd8a65fa3c37548
@@@ -18,7 -18,6 +18,7 @@@
  #include <phy.h>
  #include <errno.h>
  #include <linux/err.h>
 +#include <linux/compiler.h>
  
  /* Generic PHY support and helper functions */
  
@@@ -44,7 -43,7 +44,6 @@@ static int genphy_config_advert(struct 
  
        /* Setup standard advertisement */
        oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
--
        if (adv < 0)
                return adv;
  
@@@ -79,7 -78,7 +78,6 @@@
        if (phydev->supported & (SUPPORTED_1000baseT_Half |
                                SUPPORTED_1000baseT_Full)) {
                oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
--
                if (adv < 0)
                        return adv;
  
   */
  static int genphy_setup_forced(struct phy_device *phydev)
  {
-       int err;
        int ctl = 0;
  
        phydev->pause = phydev->asym_pause = 0;
        if (DUPLEX_FULL == phydev->duplex)
                ctl |= BMCR_FULLDPLX;
  
-       err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-       return err;
+       return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
  }
  
  
@@@ -140,7 -136,7 +135,6 @@@ int genphy_restart_aneg(struct phy_devi
        int ctl;
  
        ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
--
        if (ctl < 0)
                return ctl;
  
        /* Don't isolate the PHY if we're negotiating */
        ctl &= ~(BMCR_ISOLATE);
  
-       ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-       return ctl;
+       return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
  }
  
  
@@@ -205,13 -199,16 +197,16 @@@ int genphy_config_aneg(struct phy_devic
   */
  int genphy_update_link(struct phy_device *phydev)
  {
-       unsigned int mii_reg;
+       int mii_reg;
+       int bmcr;
  
        /*
         * Wait if the link is up, and autonegotiation is in progress
         * (ie - we're capable and it's not done)
         */
        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+       if (mii_reg < 0)
+               return mii_reg;
  
        /*
         * If we already saw the link up, and it hasn't gone down, then
        if (phydev->link && mii_reg & BMSR_LSTATUS)
                return 0;
  
+       bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+       if (bmcr < 0)
+               return bmcr;
+       if (!(bmcr & BMCR_ANENABLE))
+               return 0;
        if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
                int i = 0;
  
  
                        udelay(1000);   /* 1 ms */
                        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+                       if (mii_reg < 0)
+                               return mii_reg;
                }
                printf(" done\n");
                phydev->link = 1;
        } else {
                /* Read the link a second time to clear the latched state */
                mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+               if (mii_reg < 0)
+                       return mii_reg;
  
                if (mii_reg & BMSR_LSTATUS)
                        phydev->link = 1;
@@@ -275,25 -283,30 +281,33 @@@ int genphy_parse_link(struct phy_devic
  {
        int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
  
+       if (mii_reg < 0)
+               return mii_reg;
        /* We're using autonegotiation */
 -      if (mii_reg & BMSR_ANEGCAPABLE) {
 +      if (phydev->supported & SUPPORTED_Autoneg) {
+               int ret;
 -              u16 lpa;
 -              u16 gblpa = 0;
 -              int estatus = 0;
 +              u32 lpa = 0;
-               int gblpa = 0;
++              u32 gblpa = 0;
 +              u32 estatus = 0;
  
                /* Check for gigabit capability */
 -              if (mii_reg & BMSR_ERCAP) {
 +              if (phydev->supported & (SUPPORTED_1000baseT_Full |
 +                                      SUPPORTED_1000baseT_Half)) {
                        /* We want a list of states supported by
                         * both PHYs in the link
                         */
-                       gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
-                       if (gblpa < 0) {
+                       ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
 -                      if (ret < 0)
 -                              return ret;
++                      if (ret < 0) {
 +                              debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
-                               gblpa = 0;
++                              ret = 0;
 +                      }
-                       gblpa &= phy_read(phydev,
-                                       MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+                       gblpa = ret;
+                       ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+                       if (ret < 0)
+                               return ret;
+                       gblpa &= ret << 2;
                }
  
                /* Set the baseline so we only have to set them
                        return 0;
                }
  
-               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
-               lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+               if (ret < 0)
+                       return ret;
+               lpa = ret;
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               if (ret < 0)
+                       return ret;
+               lpa &= ret;
  
                if (lpa & (LPA_100FULL | LPA_100HALF)) {
                        phydev->speed = SPEED_100;
                if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
                        estatus = phy_read(phydev, MDIO_DEVAD_NONE,
                                           MII_ESTATUS);
+               if (estatus < 0)
+                       return estatus;
  
                if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
                                ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
                }
  
        } else {
-               u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+               int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+               if (bmcr < 0)
+                       return bmcr;
  
                phydev->speed = SPEED_10;
                phydev->duplex = DUPLEX_HALF;
@@@ -375,7 -400,7 +401,6 @@@ int genphy_config(struct phy_device *ph
  
        /* Do we support autonegotiation? */
        val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
--
        if (val < 0)
                return val;
  
@@@ -448,15 -473,15 +473,15 @@@ int phy_init(void
  #ifdef CONFIG_PHY_BROADCOM
        phy_broadcom_init();
  #endif
 +#ifdef CONFIG_PHY_CORTINA
 +      phy_cortina_init();
 +#endif
  #ifdef CONFIG_PHY_DAVICOM
        phy_davicom_init();
  #endif
  #ifdef CONFIG_PHY_ET1011C
        phy_et1011c_init();
  #endif
 -#ifdef CONFIG_PHY_ICPLUS
 -      phy_icplus_init();
 -#endif
  #ifdef CONFIG_PHY_LXT
        phy_lxt_init();
  #endif
@@@ -533,6 -558,69 +558,69 @@@ static struct phy_driver *get_phy_drive
        return generic_for_interface(interface);
  }
  
+ static int aneg_enabled(struct phy_device *phydev)
+ {
+       static const char *aneg = "_aneg";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+       return getenv_yesno(varname);
+ }
+ static int phy_get_speed(struct phy_device *phydev)
+ {
+       int ret;
+       static const char *aneg = "_speed";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+       ulong val;
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+       val = getenv_ulong(varname, 10, 100);
+       switch (val) {
+       case 1000:
+               ret = SPEED_1000;
+               break;
+       case 100:
+               ret = SPEED_100;
+               break;
+       case 10:
+               ret = SPEED_10;
+               break;
+       default:
+               printf("Improper setting '%s' for %s; assuming 100\n",
+                       getenv(varname), varname);
+               ret = SPEED_100;
+       }
+       return ret;
+ }
+ static int phy_get_duplex(struct phy_device *phydev)
+ {
+       int ret = DUPLEX_FULL;
+       static const char *aneg = "_duplex";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 4];
+       const char *val;
+       snprintf(varname, sizeof(varname), "%s%d%s",
+               phydev->bus->name, phydev->addr, aneg);
+       val = getenv(varname);
+       if (val != NULL) {
+               if (strcasecmp(val, "full") != 0) {
+                       if (strcasecmp(val, "half") == 0) {
+                               ret = DUPLEX_HALF;
+                       } else {
+                               printf("Improper setting '%s' for %s; assuming 'full'\n",
+                                       val, varname);
+                               printf("Expected one of: 'full', 'half'\n");
+                       }
+               }
+       }
+       return ret;
+ }
  static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
                                            int phy_id,
                                            phy_interface_t interface)
        dev->link = 1;
        dev->interface = interface;
  
-       dev->autoneg = AUTONEG_ENABLE;
        dev->addr = addr;
        dev->phy_id = phy_id;
        dev->bus = bus;
  
        dev->drv = get_phy_driver(dev, interface);
  
+       if (aneg_enabled(dev)) {
+               dev->autoneg = AUTONEG_ENABLE;
+       } else {
+               dev->autoneg = AUTONEG_DISABLE;
+               dev->speed = phy_get_speed(dev);
+               dev->duplex = phy_get_duplex(dev);
+               switch (dev->speed) {
+               case SPEED_1000:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_1000baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_1000baseT_Half;
+                       break;
+               case SPEED_100:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_100baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_100baseT_Half;
+                       break;
+               case SPEED_10:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_10baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_10baseT_Half;
+                       break;
+               default:
+                       printf("Unsupported speed: %d\n", dev->speed);
+               }
+       }
        phy_probe(dev);
  
        bus->phymap[addr] = dev;
@@@ -609,8 -726,10 +726,8 @@@ static struct phy_device *create_phy_by
        while (phy_mask) {
                int addr = ffs(phy_mask) - 1;
                int r = get_phy_id(bus, addr, devad, &phy_id);
 -              if (r < 0)
 -                      return ERR_PTR(r);
                /* If the PHY ID is mostly f's, we didn't find anything */
 -              if ((phy_id & 0x1fffffff) != 0x1fffffff)
 +              if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff)
                        return phy_device_create(bus, addr, phy_id, interface);
                phy_mask &= ~(1 << addr);
        }
@@@ -651,7 -770,7 +768,7 @@@ static struct phy_device *get_phy_devic
                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);
  }
  
@@@ -671,6 -790,7 +788,7 @@@ static struct phy_device *get_phy_devic
  
  int phy_reset(struct phy_device *phydev)
  {
+       int err;
        int reg;
        int timeout = 500;
        int devad = MDIO_DEVAD_NONE;
  
        reg |= BMCR_RESET;
  
-       if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
+       err = phy_write(phydev, devad, MII_BMCR, reg);
+       if (err < 0) {
                debug("PHY reset failed\n");
-               return -1;
+               return err;
        }
  
  #ifdef CONFIG_PHY_RESET_DELAY
         * auto-clearing).  This should happen within 0.5 seconds per the
         * IEEE spec.
         */
-       while ((reg & BMCR_RESET) && timeout--) {
+       while ((reg & BMCR_RESET) && timeout-- >= 0) {
                reg = phy_read(phydev, devad, MII_BMCR);
  
                if (reg < 0) {
                        debug("PHY status read failed\n");
-                       return -1;
+                       return reg;
                }
                udelay(1000);
        }
  
        if (reg & BMCR_RESET) {
                puts("PHY reset timed out\n");
-               return -1;
+               return -ETIMEDOUT;
        }
  
        return 0;
@@@ -788,13 -909,16 +907,13 @@@ int phy_startup(struct phy_device *phyd
        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 */
diff --combined drivers/net/phy/smsc.c
index bfd9815abf9b68dcb52eb11cb5ed9ec38f559c97,c562f9f0bea5719ee8707c782e8dcf437d35c411..1001d448524c90fda2a72c04abb15e48ebdab8c0
   *   Copyright 2010-2011 Freescale Semiconductor, Inc.
   *   author Andy Fleming
   *
 - * Some code get from linux kenrel
 + * Some code copied from linux kernel
   * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
   */
  #include <miiphy.h>
+ #include <errno.h>
+ #define MII_LAN83C185_CTRL_STATUS     17 /* Mode/Status Register */
+ #define MII_LAN83C185_EDPWRDOWN               (1 << 13) /* EDPWRDOWN */
+ #define MII_LAN83C185_ENERGYON                (1 << 1)  /* ENERGYON */
  
 +/* This code does not check the partner abilities. */
  static int smsc_parse_status(struct phy_device *phydev)
  {
-       int mii_reg;
+       int bmcr;
+       int aneg_exp;
+       int mii_adv;
+       int lpa;
+       aneg_exp = phy_read(phydev, MDIO_DEVAD_NONE, MII_EXPANSION);
+       if (aneg_exp < 0)
+               return aneg_exp;
+       if (aneg_exp & EXPANSION_MFAULTS) {
+               /* second read to clear latched status */
+               aneg_exp = phy_read(phydev, MDIO_DEVAD_NONE, MII_EXPANSION);
+               if (aneg_exp & EXPANSION_MFAULTS)
+                       return -EIO;
+       }
  
-       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+       bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+       if (bmcr < 0)
+               return bmcr;
+       if (bmcr & BMCR_ANENABLE) {
+               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               if (lpa < 0)
+                       return lpa;
+               mii_adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+               if (mii_adv < 0)
+                       return mii_adv;
+               lpa &= mii_adv;
  
-       if (mii_reg & (BMSR_100FULL | BMSR_100HALF))
-               phydev->speed = SPEED_100;
-       else
-               phydev->speed = SPEED_10;
+               if (!(aneg_exp & EXPANSION_NWAY)) {
+                       /* parallel detection */
+                       phydev->duplex = DUPLEX_HALF;
+                       if (lpa & (LPA_100HALF | LPA_100FULL))
+                               phydev->speed = SPEED_100;
+                       else
+                               phydev->speed = SPEED_10;
+               }
  
-       if (mii_reg & (BMSR_10FULL | BMSR_100FULL))
-               phydev->duplex = DUPLEX_FULL;
-       else
-               phydev->duplex = DUPLEX_HALF;
+               if (lpa & (LPA_100FULL | LPA_100HALF)) {
+                       phydev->speed = SPEED_100;
+                       if (lpa & LPA_100FULL)
+                               phydev->duplex = DUPLEX_FULL;
+                       else
+                               phydev->duplex = DUPLEX_HALF;
+               } else if (lpa & (LPA_10FULL | LPA_10HALF)) {
+                       phydev->speed = SPEED_10;
+                       if (lpa & LPA_10FULL)
+                               phydev->duplex = DUPLEX_FULL;
+                       else
+                               phydev->duplex = DUPLEX_HALF;
+               } else {
+                       return -EINVAL;
+               }
+       } else {
+               if (bmcr & BMCR_SPEED100)
+                       phydev->speed = SPEED_100;
+               else
+                       phydev->speed = SPEED_10;
  
+               if (bmcr & BMCR_FULLDPLX)
+                       phydev->duplex = DUPLEX_FULL;
+               else
+                       phydev->duplex = DUPLEX_HALF;
+       }
        return 0;
  }
  
  static int smsc_startup(struct phy_device *phydev)
  {
-       genphy_update_link(phydev);
-       smsc_parse_status(phydev);
-       return 0;
+       int ret;
+       if (!phydev->link) {
+               /* Disable EDPD to wake up PHY */
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_LAN83C185_CTRL_STATUS);
+               if (ret < 0)
+                       return ret;
+               if (ret & MII_LAN83C185_EDPWRDOWN) {
+                       ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_LAN83C185_CTRL_STATUS,
+                               ret & ~MII_LAN83C185_EDPWRDOWN);
+                       if (ret < 0)
+                               return ret;
+                       /* Sleep 64 ms to allow ~5 link test pulses to be sent */
+                       udelay(64 * 1000);
+               }
+       }
+       ret = genphy_update_link(phydev);
+       if (ret < 0)
+               return ret;
+       return smsc_parse_status(phydev);
+ }
+ static int smsc_mdix_setup(struct phy_device *phydev)
+ {
+       int ret;
+       static const char *mdix = "_mdi";
+       char varname[strlen(phydev->bus->name) + strlen(mdix) + 1];
+       const char *val;
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, mdix);
+       val = getenv(varname);
+       if (val) {
+               if (strcasecmp(val, "auto") == 0) {
+                       ret = 0;
+               } else if (strcasecmp(val, "mdix") == 0) {
+                       ret = 1;
+               } else if (strcasecmp(val, "mdi") == 0) {
+                       ret = 2;
+               } else {
+                       printf("Improper setting '%s' for %s\n", val, varname);
+                       printf("Expected one of: 'auto', 'mdi', 'mdix'\n");
+                       return -EINVAL;
+               }
+       } else {
+               ret = 0;
+       }
+       return ret;
+ }
+ static int smsc_config(struct phy_device *phydev)
+ {
+       int mdix = smsc_mdix_setup(phydev);
+       if (mdix < 0) {
+               return mdix;
+       } else if (mdix) {
+               int ret = phy_write(phydev, MDIO_DEVAD_NONE, 0x1b,
+                               (1 << 15) | ((mdix & 1) << 13));
+               if (ret) {
+                       printf("Failed to setup MDI/MDIX mode: %d\n", ret);
+                       return ret;
+               }
+       }
+       return genphy_config_aneg(phydev);
  }
  
  static struct phy_driver lan8700_driver = {
@@@ -63,9 -182,9 +183,9 @@@ static struct phy_driver lan8710_drive
        .name = "SMSC LAN8710/LAN8720",
        .uid = 0x0007c0f0,
        .mask = 0xffff0,
 -      .features = PHY_GBIT_FEATURES,
 +      .features = PHY_BASIC_FEATURES,
-       .config = &genphy_config_aneg,
-       .startup = &genphy_startup,
+       .config = &smsc_config,
+       .startup = &smsc_startup,
        .shutdown = &genphy_shutdown,
  };
  
index d6cf1d874a60c72c747489849bf58cffc915e57c,451e9a228f87687d34b6c5502c50ae6808e9bfc6..a9ca92107156e8901ae74f9ef0e6b0906fa380ee
@@@ -5,15 -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)
@@@ -55,7 -77,7 +55,7 @@@
  #define  UCR3_DSR        (1<<10) /* Data set ready */
  #define  UCR3_DCD        (1<<9)  /* Data carrier detect */
  #define  UCR3_RI         (1<<8)  /* Ring indicator */
 -#define  UCR3_TIMEOUTEN  (1<<7)  /* Timeout interrupt enable */
 +#define  UCR3_ADNIMP     (1<<7)  /* Autobaud Detection Not Improved */
  #define  UCR3_RXDSEN   (1<<6)  /* Receive status interrupt enable */
  #define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
  #define  UCR3_AWAKEN   (1<<4)  /* Async wake interrupt enable */
  #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)
@@@ -157,15 -152,15 +157,15 @@@ static int mxc_serial_getc(void
  
  static void mxc_serial_putc(const char c)
  {
+       /* If \n, also do \r */
+       if (c == '\n')
+               serial_putc ('\r');
        __REG(UART_PHYS + UTXD) = c;
  
        /* wait for transmitter to be ready */
        while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
                WATCHDOG_RESET();
-       /* If \n, also do \r */
-       if (c == '\n')
-               serial_putc ('\r');
  }
  
  /*
@@@ -191,7 -186,7 +191,7 @@@ static int mxc_serial_init(void
  
        while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST));
  
 -      __REG(UART_PHYS + UCR3) = 0x0704;
 +      __REG(UART_PHYS + UCR3) = 0x0704 | UCR3_ADNIMP;
        __REG(UART_PHYS + UCR4) = 0x8000;
        __REG(UART_PHYS + UESC) = 0x002b;
        __REG(UART_PHYS + UTIM) = 0x0;
@@@ -227,118 -222,3 +227,118 @@@ __weak struct serial_device *default_se
  {
        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 951dd3b25f2cf766df706a4fdbf86366dbff4e05,eb24af5974fc0e6b716a5e20723a2a7923f41644..154be8cb7cbe1e01c31f9f18c917205546712c22
  #define USBPHY_CTRL_CLKGATE                   0x40000000
  #define USBPHY_CTRL_ENUTMILEVEL3              0x00008000
  #define USBPHY_CTRL_ENUTMILEVEL2              0x00004000
 +#define USBPHY_CTRL_OTG_ID                    0x08000000
  
  #define ANADIG_USB2_CHRG_DETECT_EN_B          0x00100000
  #define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B    0x00080000
  
--#define ANADIG_USB2_PLL_480_CTRL_BYPASS               0x00010000
--#define ANADIG_USB2_PLL_480_CTRL_ENABLE               0x00002000
--#define ANADIG_USB2_PLL_480_CTRL_POWER                0x00001000
--#define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS  0x00000040
++#define ANADIG_USB_PLL_480_CTRL_BYPASS                0x00010000
++#define ANADIG_USB_PLL_480_CTRL_ENABLE                0x00002000
++#define ANADIG_USB_PLL_480_CTRL_POWER         0x00001000
++#define ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS   0x00000040
  
  
  #define UCTRL_OVER_CUR_POL    (1 << 8) /* OTG Polarity of Overcurrent */
  #define UCTRL_OVER_CUR_DIS    (1 << 7) /* Disable OTG Overcurrent Detection */
  
  /* USBCMD */
 -#define UH1_USBCMD_OFFSET     0x140
  #define UCMD_RUN_STOP           (1 << 0) /* controller run/stop */
  #define UCMD_RESET            (1 << 1) /* controller reset */
  
 -static void usbh1_internal_phy_clock_gate(int on)
 +static const unsigned phy_bases[] = {
 +      USB_PHY0_BASE_ADDR,
 +      USB_PHY1_BASE_ADDR,
 +};
 +
 +static void usb_internal_phy_clock_gate(int index, int on)
  {
 -      void __iomem *phy_reg = (void __iomem *)USB_PHY1_BASE_ADDR;
 +      void __iomem *phy_reg;
 +
 +      if (index >= ARRAY_SIZE(phy_bases))
 +              return;
  
 +      phy_reg = (void __iomem *)phy_bases[index];
        phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET;
        __raw_writel(USBPHY_CTRL_CLKGATE, phy_reg);
  }
  
 -static void usbh1_power_config(void)
 +static void usb_power_config(int index)
  {
        struct anatop_regs __iomem *anatop =
                (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 +      void __iomem *chrg_detect;
 +      void __iomem *pll_480_ctrl_clr;
 +      void __iomem *pll_480_ctrl_set;
 +
 +      switch (index) {
 +      case 0:
 +              chrg_detect = &anatop->usb1_chrg_detect;
 +              pll_480_ctrl_clr = &anatop->usb1_pll_480_ctrl_clr;
 +              pll_480_ctrl_set = &anatop->usb1_pll_480_ctrl_set;
 +              break;
 +      case 1:
 +              chrg_detect = &anatop->usb2_chrg_detect;
 +              pll_480_ctrl_clr = &anatop->usb2_pll_480_ctrl_clr;
 +              pll_480_ctrl_set = &anatop->usb2_pll_480_ctrl_set;
 +              break;
 +      default:
 +              return;
 +      }
        /*
 -       * Some phy and power's special controls for host1
 +       * Some phy and power's special controls
         * 1. The external charger detector needs to be disabled
         * or the signal at DP will be poor
 -       * 2. The PLL's power and output to usb for host 1
 +       * 2. The PLL's power and output to usb
         * is totally controlled by IC, so the Software only needs
         * to enable them at initializtion.
         */
        __raw_writel(ANADIG_USB2_CHRG_DETECT_EN_B |
                     ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
 -                   &anatop->usb2_chrg_detect);
 +                   chrg_detect);
  
--      __raw_writel(ANADIG_USB2_PLL_480_CTRL_BYPASS,
 -                   &anatop->usb2_pll_480_ctrl_clr);
++      __raw_writel(ANADIG_USB_PLL_480_CTRL_BYPASS,
 +                   pll_480_ctrl_clr);
  
--      __raw_writel(ANADIG_USB2_PLL_480_CTRL_ENABLE |
--                   ANADIG_USB2_PLL_480_CTRL_POWER |
--                   ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
 -                   &anatop->usb2_pll_480_ctrl_set);
++      __raw_writel(ANADIG_USB_PLL_480_CTRL_ENABLE |
++                   ANADIG_USB_PLL_480_CTRL_POWER |
++                   ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS,
 +                   pll_480_ctrl_set);
  }
  
 -static int usbh1_phy_enable(void)
 +/* Return 0 : host node, <>0 : device mode */
 +static int usb_phy_enable(int index, struct usb_ehci *ehci)
  {
 -      void __iomem *phy_reg = (void __iomem *)USB_PHY1_BASE_ADDR;
 -      void __iomem *phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
 -      void __iomem *usb_cmd = (void __iomem *)(USBOH3_USB_BASE_ADDR +
 -                                               USB_H1REGS_OFFSET +
 -                                               UH1_USBCMD_OFFSET);
 +      void __iomem *phy_reg;
 +      void __iomem *phy_ctrl;
 +      void __iomem *usb_cmd;
        u32 val;
  
 +      if (index >= ARRAY_SIZE(phy_bases))
 +              return 0;
 +
 +      phy_reg = (void __iomem *)phy_bases[index];
 +      phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
 +      usb_cmd = (void __iomem *)&ehci->usbcmd;
 +
        /* Stop then Reset */
        val = __raw_readl(usb_cmd);
        val &= ~UCMD_RUN_STOP;
        /* Power up the PHY */
        __raw_writel(0, phy_reg + USBPHY_PWD);
        /* enable FS/LS device */
 -      val = __raw_readl(phy_reg + USBPHY_CTRL);
 +      val = __raw_readl(phy_ctrl);
        val |= (USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3);
 -      __raw_writel(val, phy_reg + USBPHY_CTRL);
 +      __raw_writel(val, phy_ctrl);
  
        return 0;
  }
  
 -static void usbh1_oc_config(void)
 +/* Base address for this IP block is 0x02184800 */
 +struct usbnc_regs {
 +      u32     ctrl[4];        /* otg/host1-3 */
 +      u32     uh2_hsic_ctrl;
 +      u32     uh3_hsic_ctrl;
 +      u32     otg_phy_ctrl_0;
 +      u32     uh1_phy_ctrl_0;
 +};
 +
 +static void usb_oc_config(int index)
  {
 -      void __iomem *usb_base = (void __iomem *)USBOH3_USB_BASE_ADDR;
 -      void __iomem *usbother_base = usb_base + USB_OTHERREGS_OFFSET;
 +      struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
 +                      USB_OTHERREGS_OFFSET);
 +      void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
        u32 val;
  
 -      val = __raw_readl(usbother_base + USB_H1_CTRL_OFFSET);
 +      val = __raw_readl(ctrl);
  #if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2
        /* mx6qarm2 seems to required a different setting*/
        val &= ~UCTRL_OVER_CUR_POL;
  #else
        val |= UCTRL_OVER_CUR_POL;
  #endif
 -      __raw_writel(val, usbother_base + USB_H1_CTRL_OFFSET);
 +      __raw_writel(val, ctrl);
  
 -      val = __raw_readl(usbother_base + USB_H1_CTRL_OFFSET);
 +      val = __raw_readl(ctrl);
        val |= UCTRL_OVER_CUR_DIS;
 -      __raw_writel(val, usbother_base + USB_H1_CTRL_OFFSET);
 +      __raw_writel(val, ctrl);
 +}
 +
 +int usb_phy_mode(int port)
 +{
 +      void __iomem *phy_reg;
 +      void __iomem *phy_ctrl;
 +      u32 val;
 +
 +      phy_reg = (void __iomem *)phy_bases[port];
 +      phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
 +
 +      val = __raw_readl(phy_ctrl);
 +
 +      if (val & USBPHY_CTRL_OTG_ID)
 +              return USB_INIT_DEVICE;
 +      else
 +              return USB_INIT_HOST;
 +}
 +
 +int __weak board_usb_phy_mode(int port)
 +{
 +      return usb_phy_mode(port);
  }
  
  int __weak board_ehci_hcd_init(int port)
        return 0;
  }
  
 -int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 +int __weak board_ehci_power(int port, int on)
  {
 -      struct usb_ehci *ehci;
 +      return 0;
 +}
  
 +int ehci_hcd_init(int index, enum usb_init_type init,
 +              struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 +{
 +      enum usb_init_type type;
 +      struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
 +              (0x200 * index));
 +
 +      if (index > 3)
 +              return -EINVAL;
        enable_usboh3_clk(1);
        mdelay(1);
  
        /* Do board specific initialization */
 -      board_ehci_hcd_init(CONFIG_MXC_USB_PORT);
 -
 -#if CONFIG_MXC_USB_PORT == 1
 -      /* USB Host 1 */
 -      usbh1_power_config();
 -      usbh1_oc_config();
 -      usbh1_internal_phy_clock_gate(1);
 -      usbh1_phy_enable();
 -#else
 -#error "MXC USB port not yet supported"
 -#endif
 +      board_ehci_hcd_init(index);
 +
 +      usb_power_config(index);
 +      usb_oc_config(index);
 +      usb_internal_phy_clock_gate(index, 1);
 +      usb_phy_enable(index, ehci);
 +      type = board_usb_phy_mode(index);
  
 -      ehci = (struct usb_ehci *)(USBOH3_USB_BASE_ADDR +
 -              (0x200 * CONFIG_MXC_USB_PORT));
        *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
        *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
                        HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 -      setbits_le32(&ehci->usbmode, CM_HOST);
  
 +      if ((type == init) || (type == USB_INIT_DEVICE))
 +              board_ehci_power(index, (type == USB_INIT_DEVICE) ? 0 : 1);
 +      if (type != init)
 +              return -ENODEV;
 +      if (type == USB_INIT_DEVICE)
 +              return 0;
 +      setbits_le32(&ehci->usbmode, CM_HOST);
        __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
        setbits_le32(&ehci->portsc, USB_EN);
  
index 5873531953316a25799c020206328bd84280b97d,cf935f577e5efa7c61b4c0d60b32a7b32ca25ddf..7e249f67ab40a572888591f96700e2a1ad32a6e1
@@@ -4,26 -4,27 +4,27 @@@
   * (C) Copyright 2010
   * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   *
-  * Linux IPU driver for MX51:
+  * Linux IPU driver
   *
-  * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+  * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
  
  /* #define DEBUG */
  #include <common.h>
+ #include <ipu.h>
  #include <linux/types.h>
  #include <linux/err.h>
  #include <asm/io.h>
  #include <asm/errno.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/crm_regs.h>
- #include "ipu.h"
+ #include <asm/arch/clock.h>
  #include "ipu_regs.h"
  
- extern struct mxc_ccm_reg *mxc_ccm;
- extern u32 *ipu_cpmem_base;
+ static struct mxc_ccm_reg __maybe_unused *mxc_ccm = (void *)CCM_BASE_ADDR;
  
  struct ipu_ch_param_word {
        uint32_t data[5];
@@@ -37,202 -38,104 +38,104 @@@ struct ipu_ch_param 
  #define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch))
  
  #define _param_word(base, w) \
-       (((struct ipu_ch_param *)(base))->word[(w)].data)
+       (((struct ipu_ch_param *)(base))->word[w].data)
  
- #define ipu_ch_param_set_field(base, w, bit, size, v) { \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       _param_word(base, w)[i] |= (v) << off; \
-       if (((bit) + (size) - 1) / 32 > i) { \
+ #define ipu_ch_param_set_field(base, w, bit, size, v) {                       \
+       int i = (bit) / 32;                                             \
+       int off = (bit) % 32;                                           \
+       _param_word(base, w)[i] |= (v) << off;                          \
+       if (((bit) + (size) - 1) / 32 > i) {                            \
                _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
-       } \
+       }                                                               \
  }
  
- #define ipu_ch_param_mod_field(base, w, bit, size, v) { \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       u32 mask = (1UL << size) - 1; \
-       u32 temp = _param_word(base, w)[i]; \
-       temp &= ~(mask << off); \
-       _param_word(base, w)[i] = temp | (v) << off; \
-       if (((bit) + (size) - 1) / 32 > i) { \
-               temp = _param_word(base, w)[i + 1]; \
-               temp &= ~(mask >> (32 - off)); \
-               _param_word(base, w)[i + 1] = \
+ #define ipu_ch_param_mod_field(base, w, bit, size, v) {               \
+       int i = (bit) / 32;                                     \
+       int off = (bit) % 32;                                   \
+       u32 mask = (1UL << size) - 1;                           \
+       u32 temp = _param_word(base, w)[i];                     \
+       temp &= ~(mask << off);                                 \
+       _param_word(base, w)[i] = temp | (v) << off;            \
+       if (((bit) + (size) - 1) / 32 > i) {                    \
+               temp = _param_word(base, w)[i + 1];             \
+               temp &= ~(mask >> (32 - off));                  \
+               _param_word(base, w)[i + 1] =                   \
                        temp | ((v) >> (off ? (32 - off) : 0)); \
-       } \
+       }                                                       \
  }
  
- #define ipu_ch_param_read_field(base, w, bit, size) ({ \
-       u32 temp2; \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       u32 mask = (1UL << size) - 1; \
-       u32 temp1 = _param_word(base, w)[i]; \
-       temp1 = mask & (temp1 >> off); \
-       if (((bit)+(size) - 1) / 32 > i) { \
-               temp2 = _param_word(base, w)[i + 1]; \
-               temp2 &= mask >> (off ? (32 - off) : 0); \
-               temp1 |= temp2 << (off ? (32 - off) : 0); \
-       } \
-       temp1; \
+ #define ipu_ch_param_read_field(base, w, bit, size) ({                \
+       u32 temp2;                                              \
+       int i = (bit) / 32;                                     \
+       int off = (bit) % 32;                                   \
+       u32 mask = (1UL << size) - 1;                           \
+       u32 temp1 = _param_word(base, w)[i];                    \
+       temp1 = mask & (temp1 >> off);                          \
+       if (((bit)+(size) - 1) / 32 > i) {                      \
+               temp2 = _param_word(base, w)[i + 1];            \
+               temp2 &= mask >> (off ? (32 - off) : 0);        \
+               temp1 |= temp2 << (off ? (32 - off) : 0);       \
+       }                                                       \
+       temp1;                                                  \
  })
  
- #define IPU_SW_RST_TOUT_USEC  (10000)
- void clk_enable(struct clk *clk)
- {
-       if (clk) {
-               if (clk->usecount++ == 0) {
-                       clk->enable(clk);
-               }
-       }
- }
- void clk_disable(struct clk *clk)
- {
-       if (clk) {
-               if (!(--clk->usecount)) {
-                       if (clk->disable)
-                               clk->disable(clk);
-               }
-       }
- }
- int clk_get_usecount(struct clk *clk)
- {
-       if (clk == NULL)
-               return 0;
-       return clk->usecount;
- }
- u32 clk_get_rate(struct clk *clk)
- {
-       if (!clk)
-               return 0;
-       return clk->rate;
- }
- struct clk *clk_get_parent(struct clk *clk)
- {
-       if (!clk)
-               return 0;
-       return clk->parent;
- }
- int clk_set_rate(struct clk *clk, unsigned long rate)
- {
-       if (clk && clk->set_rate)
-               clk->set_rate(clk, rate);
-       return clk->rate;
- }
- long clk_round_rate(struct clk *clk, unsigned long rate)
- {
-       if (clk == NULL || !clk->round_rate)
-               return 0;
-       return clk->round_rate(clk, rate);
- }
- int clk_set_parent(struct clk *clk, struct clk *parent)
- {
-       clk->parent = parent;
-       if (clk->set_parent)
-               return clk->set_parent(clk, parent);
-       return 0;
- }
+ #define IPU_SW_RST_TOUT_USEC  10000
  
  static int clk_ipu_enable(struct clk *clk)
  {
-       u32 reg;
-       reg = __raw_readl(clk->enable_reg);
-       reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
-       __raw_writel(reg, clk->enable_reg);
- #if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       /* Handshake with IPU when certain clock rates are changed. */
-       reg = __raw_readl(&mxc_ccm->ccdr);
-       reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
-       __raw_writel(reg, &mxc_ccm->ccdr);
-       /* Handshake with IPU when LPM is entered as its enabled. */
-       reg = __raw_readl(&mxc_ccm->clpcr);
-       reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
-       __raw_writel(reg, &mxc_ccm->clpcr);
- #endif
+       ipu_clk_enable();
        return 0;
  }
  
  static void clk_ipu_disable(struct clk *clk)
  {
-       u32 reg;
-       reg = __raw_readl(clk->enable_reg);
-       reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
-       __raw_writel(reg, clk->enable_reg);
- #if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       /*
-        * No handshake with IPU whe dividers are changed
-        * as its not enabled.
-        */
-       reg = __raw_readl(&mxc_ccm->ccdr);
-       reg |= MXC_CCM_CCDR_IPU_HS_MASK;
-       __raw_writel(reg, &mxc_ccm->ccdr);
-       /* No handshake with IPU when LPM is entered as its not enabled. */
-       reg = __raw_readl(&mxc_ccm->clpcr);
-       reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
-       __raw_writel(reg, &mxc_ccm->clpcr);
- #endif
+       ipu_clk_disable();
  }
  
  static struct clk ipu_clk = {
        .name = "ipu_clk",
        .rate = CONFIG_IPUV3_CLK,
- #if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       .enable_reg = (u32 *)(CCM_BASE_ADDR +
-               offsetof(struct mxc_ccm_reg, CCGR5)),
-       .enable_shift = MXC_CCM_CCGR5_IPU_OFFSET,
- #else
-       .enable_reg = (u32 *)(CCM_BASE_ADDR +
-               offsetof(struct mxc_ccm_reg, CCGR3)),
-       .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET,
- #endif
        .enable = clk_ipu_enable,
        .disable = clk_ipu_disable,
-       .usecount = 0,
  };
  
+ static int clk_ldb_enable(struct clk *clk)
+ {
+       ldb_clk_enable(0);
+       ldb_clk_enable(1);
+       return 0;
+ }
+ static void clk_ldb_disable(struct clk *clk)
+ {
+       ldb_clk_disable(0);
+       ldb_clk_disable(1);
+ }
  static struct clk ldb_clk = {
        .name = "ldb_clk",
        .rate = 65000000,
-       .usecount = 0,
+       .enable = clk_ldb_enable,
+       .disable = clk_ldb_disable,
  };
  
  /* Globals */
  struct clk *g_ipu_clk;
  struct clk *g_ldb_clk;
- unsigned char g_ipu_clk_enabled;
  struct clk *g_di_clk[2];
  struct clk *g_pixel_clk[2];
  unsigned char g_dc_di_assignment[10];
uint32_t g_channel_init_mask;
- uint32_t g_channel_enable_mask;
int g_ipu_clk_enabled;
+ u32 *ipu_dc_tmpl_reg;
  
+ static uint32_t g_channel_init_mask;
+ static uint32_t g_channel_enable_mask;
  static int ipu_dc_use_count;
  static int ipu_dp_use_count;
  static int ipu_dmfc_use_count;
  static int ipu_di_use_count[2];
  
- u32 *ipu_cpmem_base;
- u32 *ipu_dc_tmpl_reg;
+ static u32 *ipu_cpmem_base;
  
  /* Static functions */
  
@@@ -282,13 -185,13 +185,13 @@@ static unsigned long ipu_pixel_clk_roun
        unsigned long rate)
  {
        u32 div, div1;
-       u32 tmp;
+       u64 tmp;
        /*
         * Calculate divider
         * Fractional part is 4 bits,
         * so simply multiply by 2^4 to get fractional part.
         */
-       tmp = (clk->parent->rate * 16);
+       tmp = (u64)clk->parent->rate * 16;
        div = tmp / rate;
  
        if (div < 0x10)            /* Min DI disp clock divider is 1 */
                else
                        div &= 0xFF8;
        }
-       return (clk->parent->rate * 16) / div;
+       tmp /= div;
+ #if 1
+       debug("%s: requested rate: %lu.%03luMHz parent_rate: %lu.%03luMHz actual rate: %llu.%03lluMHz div: %u.%u\n", __func__,
+               rate / 1000000, rate / 1000 % 1000,
+               clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
+               tmp / 1000000, tmp / 1000 % 1000, div / 16, div % 16);
+ #endif
+       return tmp;
  }
  
  static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
  {
-       u32 div = (clk->parent->rate * 16) / rate;
+       u32 div = ((u64)clk->parent->rate * 16) / rate;
+       debug("%s: parent_rate: %lu.%03luMHz actual rate: %lu.%03luMHz div: %u.%u\n", __func__,
+               clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
+               rate / 1000000, rate / 1000 % 1000, div / 16, div % 16);
  
        __raw_writel(div, DI_BS_CLKGEN0(clk->id));
  
        /* Setup pixel clock timing */
        __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
  
-       clk->rate = (clk->parent->rate * 16) / div;
+       clk->rate = ((u64)clk->parent->rate * 16) / div;
+       debug("%s: pix_clk=%lu.%03luMHz\n", __func__,
+               clk->rate / 1000000, clk->rate / 1000 % 1000);
        return 0;
  }
  
@@@ -332,54 -248,91 +248,91 @@@ static void ipu_pixel_clk_disable(struc
        u32 disp_gen = __raw_readl(IPU_DISP_GEN);
        disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
        __raw_writel(disp_gen, IPU_DISP_GEN);
  }
  
  static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent)
  {
-       u32 di_gen = __raw_readl(DI_GENERAL(clk->id));
+       int ret;
+       u32 di_gen;
+       ret = clk_enable(clk);
+       if (ret)
+               return ret;
+       di_gen = __raw_readl(DI_GENERAL(clk->id));
  
        if (parent == g_ipu_clk)
                di_gen &= ~DI_GEN_DI_CLK_EXT;
        else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_ldb_clk)
                di_gen |= DI_GEN_DI_CLK_EXT;
        else
-               return -EINVAL;
+               goto err;
  
+       ret = clk_enable(parent);
+       if (ret)
+               goto err;
        __raw_writel(di_gen, DI_GENERAL(clk->id));
        ipu_pixel_clk_recalc(clk);
-       return 0;
+       clk->disable(clk->parent);
+       clk->parent = parent;
+ err:
+       clk_disable(clk);
+       return ret;
  }
  
  static struct clk pixel_clk[] = {
        {
-       .name = "pixel_clk",
-       .id = 0,
-       .recalc = ipu_pixel_clk_recalc,
-       .set_rate = ipu_pixel_clk_set_rate,
-       .round_rate = ipu_pixel_clk_round_rate,
-       .set_parent = ipu_pixel_clk_set_parent,
-       .enable = ipu_pixel_clk_enable,
-       .disable = ipu_pixel_clk_disable,
-       .usecount = 0,
+               .name = "pixel_clk",
+               .id = 0,
+               .recalc = ipu_pixel_clk_recalc,
+               .set_rate = ipu_pixel_clk_set_rate,
+               .round_rate = ipu_pixel_clk_round_rate,
+               .set_parent = ipu_pixel_clk_set_parent,
+               .enable = ipu_pixel_clk_enable,
+               .disable = ipu_pixel_clk_disable,
        },
        {
-       .name = "pixel_clk",
-       .id = 1,
-       .recalc = ipu_pixel_clk_recalc,
-       .set_rate = ipu_pixel_clk_set_rate,
-       .round_rate = ipu_pixel_clk_round_rate,
-       .set_parent = ipu_pixel_clk_set_parent,
-       .enable = ipu_pixel_clk_enable,
-       .disable = ipu_pixel_clk_disable,
-       .usecount = 0,
+               .name = "pixel_clk",
+               .id = 1,
+               .recalc = ipu_pixel_clk_recalc,
+               .set_rate = ipu_pixel_clk_set_rate,
+               .round_rate = ipu_pixel_clk_round_rate,
+               .set_parent = ipu_pixel_clk_set_parent,
+               .enable = ipu_pixel_clk_enable,
+               .disable = ipu_pixel_clk_disable,
+       },
+ };
+ static int clk_ipu_di_enable(struct clk *clk)
+ {
+       ipu_di_clk_enable(clk->id);
+       return 0;
+ }
+ static void clk_ipu_di_disable(struct clk *clk)
+ {
+       ipu_di_clk_disable(clk->id);
+ }
+ static struct clk di_clk[] = {
+       {
+               .name = "ipu_di_clk",
+               .id = 0,
+               .enable = clk_ipu_di_enable,
+               .disable = clk_ipu_di_disable,
+       },
+       {
+               .name = "ipu_di_clk",
+               .id = 1,
+               .enable = clk_ipu_di_enable,
+               .disable = clk_ipu_di_disable,
        },
  };
  
  /*
   * This function resets IPU
   */
 -void ipu_reset(void)
 +static void ipu_reset(void)
  {
        u32 *reg;
        u32 value;
   *
   * @return      Returns 0 on success or negative error code on error
   */
- int ipu_probe(void)
+ int ipu_probe(int di, ipu_di_clk_parent_t di_clk_parent, int di_clk_val)
  {
-       unsigned long ipu_base;
+       int ret;
+       void *ipu_base;
+       unsigned long start;
  #if defined CONFIG_MX51
        u32 temp;
        u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR;
        u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800);
  
         __raw_writel(0xF00, reg_hsc_mcd);
  
-       /* CSI mode reserved*/
+       /* CSI mode reserved */
        temp = __raw_readl(reg_hsc_mxt_conf);
         __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf);
  
        temp = __raw_readl(reg_hsc_mxt_conf);
        __raw_writel(temp | 0x10000, reg_hsc_mxt_conf);
  #endif
-       ipu_base = IPU_CTRL_BASE_ADDR;
-       ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE);
-       ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE);
+       ipu_base = (void *)IPU_SOC_BASE_ADDR;
+       /* base fixup */
+       if (gd->arch.ipu_hw_rev == IPUV3_HW_REV_IPUV3H) /* IPUv3H */
+               ipu_base += IPUV3H_REG_BASE;
+       else if (gd->arch.ipu_hw_rev == IPUV3_HW_REV_IPUV3M)    /* IPUv3M */
+               ipu_base += IPUV3M_REG_BASE;
+       else                    /* IPUv3D, v3E, v3EX */
+               ipu_base += IPUV3DEX_REG_BASE;
+       ipu_cpmem_base = ipu_base + IPU_CPMEM_REG_BASE;
+       ipu_dc_tmpl_reg = ipu_base + IPU_DC_TMPL_REG_BASE;
+       printf("IPU HW Rev: %d\n", gd->arch.ipu_hw_rev);
  
        g_pixel_clk[0] = &pixel_clk[0];
        g_pixel_clk[1] = &pixel_clk[1];
  
+       g_di_clk[0] = &di_clk[0];
+       g_di_clk[1] = &di_clk[1];
+       g_di_clk[di]->rate = di_clk_val;
        g_ipu_clk = &ipu_clk;
        debug("ipu_clk = %u\n", clk_get_rate(g_ipu_clk));
        g_ldb_clk = &ldb_clk;
        debug("ldb_clk = %u\n", clk_get_rate(g_ldb_clk));
-       ipu_reset();
  
-       clk_set_parent(g_pixel_clk[0], g_ipu_clk);
-       clk_set_parent(g_pixel_clk[1], g_ipu_clk);
-       clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
+       ipu_reset();
  
-       g_di_clk[0] = NULL;
-       g_di_clk[1] = NULL;
+       if (di_clk_parent == DI_PCLK_LDB) {
+               clk_set_parent(g_pixel_clk[di], g_ldb_clk);
+       } else {
+               clk_set_parent(g_pixel_clk[0], g_ipu_clk);
+               clk_set_parent(g_pixel_clk[1], g_ipu_clk);
+       }
  
        __raw_writel(0x807FFFFF, IPU_MEM_RST);
-       while (__raw_readl(IPU_MEM_RST) & 0x80000000)
-               ;
+       start = get_timer_masked();
+       while (__raw_readl(IPU_MEM_RST) & 0x80000000) {
+               if (get_timer(start) > CONFIG_SYS_HZ)
+                       return -ETIME;
+       }
  
        ipu_init_dc_mappings();
  
  
  void ipu_dump_registers(void)
  {
-       debug("IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF));
-       debug("IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF));
-       debug("IDMAC_CHA_EN1 = \t0x%08X\n",
+       debug("IPU_CONF             0x%08X\n", __raw_readl(IPU_CONF));
+       debug("IDMAC_CONF           0x%08X\n", __raw_readl(IDMAC_CONF));
+       debug("IDMAC_CHA_EN1        0x%08X\n",
               __raw_readl(IDMAC_CHA_EN(0)));
-       debug("IDMAC_CHA_EN2 = \t0x%08X\n",
+       debug("IDMAC_CHA_EN2        0x%08X\n",
               __raw_readl(IDMAC_CHA_EN(32)));
-       debug("IDMAC_CHA_PRI1 = \t0x%08X\n",
+       debug("IDMAC_CHA_PRI1       0x%08X\n",
               __raw_readl(IDMAC_CHA_PRI(0)));
-       debug("IDMAC_CHA_PRI2 = \t0x%08X\n",
+       debug("IDMAC_CHA_PRI2       0x%08X\n",
               __raw_readl(IDMAC_CHA_PRI(32)));
-       debug("IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
+       debug("IPU_CHA_DB_MODE_SEL0 0x%08X\n",
               __raw_readl(IPU_CHA_DB_MODE_SEL(0)));
-       debug("IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
+       debug("IPU_CHA_DB_MODE_SEL1 0x%08X\n",
               __raw_readl(IPU_CHA_DB_MODE_SEL(32)));
-       debug("DMFC_WR_CHAN = \t0x%08X\n",
+       debug("DMFC_WR_CHAN         0x%08X\n",
               __raw_readl(DMFC_WR_CHAN));
-       debug("DMFC_WR_CHAN_DEF = \t0x%08X\n",
+       debug("DMFC_WR_CHAN_DEF     0x%08X\n",
               __raw_readl(DMFC_WR_CHAN_DEF));
-       debug("DMFC_DP_CHAN = \t0x%08X\n",
+       debug("DMFC_DP_CHAN         0x%08X\n",
               __raw_readl(DMFC_DP_CHAN));
-       debug("DMFC_DP_CHAN_DEF = \t0x%08X\n",
+       debug("DMFC_DP_CHAN_DEF     0x%08X\n",
               __raw_readl(DMFC_DP_CHAN_DEF));
-       debug("DMFC_IC_CTRL = \t0x%08X\n",
+       debug("DMFC_IC_CTRL         0x%08X\n",
               __raw_readl(DMFC_IC_CTRL));
-       debug("IPU_FS_PROC_FLOW1 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW1    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW1));
-       debug("IPU_FS_PROC_FLOW2 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW2    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW2));
-       debug("IPU_FS_PROC_FLOW3 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW3    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW3));
-       debug("IPU_FS_DISP_FLOW1 = \t0x%08X\n",
+       debug("IPU_FS_DISP_FLOW1    0x%08X\n",
               __raw_readl(IPU_FS_DISP_FLOW1));
  }
  
@@@ -578,7 -552,6 +552,6 @@@ int32_t ipu_init_channel(ipu_channel_t 
                break;
        default:
                printf("Missing channel initialization\n");
-               break;
        }
  
        /* Enable IPU sub module */
                ipu_conf |= IPU_CONF_DMFC_EN;
        if (ipu_di_use_count[0] == 1) {
                ipu_conf |= IPU_CONF_DI0_EN;
+               clk_enable(g_di_clk[0]);
        }
        if (ipu_di_use_count[1] == 1) {
                ipu_conf |= IPU_CONF_DI1_EN;
+               clk_enable(g_di_clk[1]);
        }
  
        __raw_writel(ipu_conf, IPU_CONF);
@@@ -628,8 -603,7 +603,7 @@@ void ipu_uninit_channel(ipu_channel_t c
  
        if (idma_is_set(IDMAC_CHA_EN, in_dma) ||
            idma_is_set(IDMAC_CHA_EN, out_dma)) {
-               printf(
-                       "Channel %d is not disabled, disable first\n",
+               printf("Channel %d is not disabled, disable first\n",
                        IPU_CHAN_ID(channel));
                return;
        }
                ipu_conf &= ~IPU_CONF_DP_EN;
        if (ipu_dmfc_use_count == 0)
                ipu_conf &= ~IPU_CONF_DMFC_EN;
-       if (ipu_di_use_count[0] == 0) {
+       if (ipu_di_use_count[0] == 0 && ipu_conf & IPU_CONF_DI0_EN) {
                ipu_conf &= ~IPU_CONF_DI0_EN;
+               clk_disable(g_di_clk[0]);
        }
-       if (ipu_di_use_count[1] == 0) {
+       if (ipu_di_use_count[1] == 0 && ipu_conf & IPU_CONF_DI1_EN) {
                ipu_conf &= ~IPU_CONF_DI1_EN;
+               clk_disable(g_di_clk[1]);
        }
  
        __raw_writel(ipu_conf, IPU_CONF);
  
+       /* clear interrupt status */
+       __raw_writel(__raw_readl(IPU_STAT), IPU_STAT);
        if (ipu_conf == 0) {
                clk_disable(g_ipu_clk);
                g_ipu_clk_enabled = 0;
        }
  }
  
  static inline void ipu_ch_param_dump(int ch)
@@@ -763,91 -741,88 +741,88 @@@ static void ipu_ch_param_init(int ch
  {
        uint32_t u_offset = 0;
        uint32_t v_offset = 0;
-       struct ipu_ch_param params;
-       memset(&params, 0, sizeof(params));
  
-       ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 125, 13, width - 1);
  
        if ((ch == 8) || (ch == 9) || (ch == 10)) {
-               ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
-               ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 138, 12, (height / 2) - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 102, 14, (stride * 2) - 1);
        } else {
-               ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
-               ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 138, 12, height - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1);
        }
  
-       ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
-       ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 0, 29, addr0 >> 3);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 29, 29, addr1 >> 3);
  
        switch (pixel_fmt) {
        case IPU_PIX_FMT_GENERIC:
                /*Represents 8-bit Generic data */
-               ipu_ch_param_set_field(&params, 0, 107, 3, 5);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 6);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 63);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 5);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 6);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 63);    /* burst size */
  
                break;
        case IPU_PIX_FMT_GENERIC_32:
                /*Represents 32-bit Generic data */
                break;
        case IPU_PIX_FMT_RGB565:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
  
-               ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 5, 0, 6, 5, 5, 11, 8, 16);
                break;
        case IPU_PIX_FMT_BGR24:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 1);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 19);    /* burst size */
  
-               ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 0, 8, 8, 8, 16, 8, 24);
                break;
        case IPU_PIX_FMT_RGB24:
        case IPU_PIX_FMT_YUV444:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 1);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 19);    /* burst size */
  
-               ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 16, 8, 8, 8, 0, 8, 24);
                break;
        case IPU_PIX_FMT_BGRA32:
        case IPU_PIX_FMT_BGR32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
  
-               ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 8, 8, 16, 8, 24, 8, 0);
                break;
        case IPU_PIX_FMT_RGBA32:
        case IPU_PIX_FMT_RGB32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
  
-               ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 24, 8, 16, 8, 8, 8, 0);
                break;
        case IPU_PIX_FMT_ABGR32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
  
-               ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 0, 8, 8, 8, 16, 8, 24);
                break;
        case IPU_PIX_FMT_UYVY:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 0xA);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
                break;
        case IPU_PIX_FMT_YUYV:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 0x8);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
                break;
        case IPU_PIX_FMT_YUV420P2:
        case IPU_PIX_FMT_YUV420P:
-               ipu_ch_param_set_field(&params, 1, 85, 4, 2);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 2);     /* pix format */
  
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
                v_offset = u_offset + (uv_stride * height / 2);
                /* burst size */
                if ((ch == 8) || (ch == 9) || (ch == 10)) {
-                       ipu_ch_param_set_field(&params, 1, 78, 7, 15);
+                       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);
                        uv_stride = uv_stride*2;
                } else {
-                       ipu_ch_param_set_field(&params, 1, 78, 7, 31);
+                       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);
                }
                break;
        case IPU_PIX_FMT_YVU422P:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 1);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
  
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
                break;
        case IPU_PIX_FMT_YUV422P:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 1);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
  
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
                break;
        case IPU_PIX_FMT_NV12:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 4);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 4);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
                uv_stride = stride;
                u_offset = (u == 0) ? stride * height : u;
                break;
        default:
-               puts("mxc ipu: unimplemented pixel format\n");
-               break;
+               printf("mxc ipu: unimplemented pixel format: %08x\n",
+                       pixel_fmt);
        }
  
  
        if (uv_stride)
-               ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 128, 14, uv_stride - 1);
  
        /* Get the uv offset from user when need cropping */
        if (u || v) {
        if (v_offset/8 > 0x3fffff)
                puts("The value of V offset exceeds IPU limitation\n");
  
-       ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
-       ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 46, 22, u_offset / 8);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 68, 22, v_offset / 8);
  
        debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch));
-       memcpy(ipu_ch_param_addr(ch), &params, sizeof(params));
  };
  
  /*
@@@ -968,8 -942,7 +942,7 @@@ int32_t ipu_init_channel_buffer(ipu_cha
                stride = width * bytes_per_pixel(pixel_fmt);
  
        if (stride % 4) {
-               printf(
-                       "Stride not 32-bit aligned, stride = %d\n", stride);
+               printf("Stride %d not 32-bit aligned\n", stride);
                return -EINVAL;
        }
        /* Build parameter memory data for DMA channel */
@@@ -1031,8 -1004,12 +1004,12 @@@ int32_t ipu_enable_channel(ipu_channel_
        }
  
        if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
-           (channel == MEM_FG_SYNC))
+           (channel == MEM_FG_SYNC)) {
+               reg = __raw_readl(IDMAC_WM_EN(in_dma));
+               __raw_writel(reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
                ipu_dp_dc_enable(channel);
+       }
  
        g_channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
  
@@@ -1141,32 -1118,27 +1118,27 @@@ int32_t ipu_disable_channel(ipu_channel
  uint32_t bytes_per_pixel(uint32_t fmt)
  {
        switch (fmt) {
-       case IPU_PIX_FMT_GENERIC:       /*generic data */
+       case IPU_PIX_FMT_GENERIC:       /* generic data */
        case IPU_PIX_FMT_RGB332:
        case IPU_PIX_FMT_YUV420P:
        case IPU_PIX_FMT_YUV422P:
                return 1;
-               break;
        case IPU_PIX_FMT_RGB565:
        case IPU_PIX_FMT_YUYV:
        case IPU_PIX_FMT_UYVY:
                return 2;
-               break;
        case IPU_PIX_FMT_BGR24:
        case IPU_PIX_FMT_RGB24:
                return 3;
-               break;
-       case IPU_PIX_FMT_GENERIC_32:    /*generic data */
+       case IPU_PIX_FMT_GENERIC_32:    /* generic data */
        case IPU_PIX_FMT_BGR32:
        case IPU_PIX_FMT_BGRA32:
        case IPU_PIX_FMT_RGB32:
        case IPU_PIX_FMT_RGBA32:
        case IPU_PIX_FMT_ABGR32:
                return 4;
-               break;
        default:
                return 1;
-               break;
        }
        return 0;
  }
@@@ -1186,11 -1158,9 +1158,9 @@@ ipu_color_space_t format_to_colorspace(
        case IPU_PIX_FMT_LVDS666:
        case IPU_PIX_FMT_LVDS888:
                return RGB;
-               break;
  
        default:
                return YCbCr;
-               break;
        }
        return RGB;
  }
diff --combined drivers/video/ipu_disp.c
index 4faeafb6351d4d3e75376e704b479ebad4a3c6b3,ff1e34b0ac531afddf369506075a322afb92bf3e..b5490b7980277c8097f7073094907609fd979c06
@@@ -4,9 -4,9 +4,9 @@@
   * (C) Copyright 2010
   * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   *
-  * Linux IPU driver for MX51:
+  * Linux IPU driver
   *
-  * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+  * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
  /* #define DEBUG */
  
  #include <common.h>
+ #include <ipu.h>
  #include <linux/types.h>
  #include <asm/errno.h>
  #include <asm/io.h>
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/sys_proto.h>
- #include "ipu.h"
  #include "ipu_regs.h"
  
  enum csc_type_t {
@@@ -33,7 -33,7 +33,7 @@@
  
  struct dp_csc_param_t {
        int mode;
 -      void *coeff;
 +      const int (*coeff)[5][3];
  };
  
  #define SYNC_WAVE 0
  #define DC_DISP_ID_SERIAL     2
  #define DC_DISP_ID_ASYNC      3
  
- int dmfc_type_setup;
static int dmfc_type_setup;
  static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23;
- int g_di1_tvout;
- extern struct clk *g_ipu_clk;
- extern struct clk *g_ldb_clk;
- extern struct clk *g_di_clk[2];
- extern struct clk *g_pixel_clk[2];
- extern unsigned char g_ipu_clk_enabled;
- extern unsigned char g_dc_di_assignment[];
+ static int g_di1_tvout;
  
  void ipu_dmfc_init(int dmfc_type, int first)
  {
@@@ -377,7 -369,7 +369,7 @@@ static struct dp_csc_param_t dp_csc_arr
  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,6 -597,17 +597,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;
@@@ -655,16 -658,13 +647,16 @@@ void ipu_dp_dc_disable(ipu_channel_t ch
        uint32_t csc;
        uint32_t dc_chan = 0;
        int timeout = 50;
 +      int irq = 0;
  
        dc_swap = swap;
  
        if (channel == MEM_DC_SYNC) {
                dc_chan = 1;
 +              irq = IPU_IRQ_DC_FC_1;
        } else if (channel == MEM_BG_SYNC) {
                dc_chan = 5;
 +              irq = IPU_IRQ_DP_SF_END;
        } else if (channel == MEM_FG_SYNC) {
                /* Disable FG channel */
                dc_chan = 5;
                reg ^= DC_WR_CH_CONF_PROG_DI_ID;
                __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
        } else {
 -              timeout = 50;
 -
 -              /* Wait for DC triple buffer to empty */
 -              if (g_dc_di_assignment[dc_chan] == 0)
 -                      while ((__raw_readl(DC_STAT) & 0x00000002)
 -                              != 0x00000002) {
 -                              udelay(2000);
 -                              timeout -= 2;
 -                              if (timeout <= 0)
 -                                      break;
 -                      }
 -              else if (g_dc_di_assignment[dc_chan] == 1)
 -                      while ((__raw_readl(DC_STAT) & 0x00000020)
 -                              != 0x00000020) {
 -                              udelay(2000);
 -                              timeout -= 2;
 -                              if (timeout <= 0)
 -                                      break;
 -                      }
 +              /* Make sure that we leave at the irq starting edge */
 +              __raw_writel(IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
 +              do {
 +                      reg = __raw_readl(IPUIRQ_2_STATREG(irq));
 +              } while (!(reg & IPUIRQ_2_MASK(irq)));
  
                reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
                reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
@@@ -767,15 -781,16 +759,16 @@@ void ipu_init_dc_mappings(void
        /* IPU_PIX_FMT_LVDS666 */
        ipu_dc_map_clear(4);
        ipu_dc_map_config(4, 0, 5, 0xFC);
-       ipu_dc_map_config(4, 1, 13, 0xFC);
-       ipu_dc_map_config(4, 2, 21, 0xFC);
+       ipu_dc_map_config(4, 1, 11, 0xFC);
+       ipu_dc_map_config(4, 2, 17, 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:
        case IPU_PIX_FMT_RGB24:
+       case IPU_PIX_FMT_LVDS888:
                return 0;
        case IPU_PIX_FMT_RGB666:
                return 1;
                return 4;
        }
  
-       return -1;
+       return -EINVAL;
  }
  
 -/*
 - * 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.
   *
   *              fail.
   */
  
- int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
-                           uint16_t width, uint16_t height,
-                           uint32_t pixel_fmt,
-                           uint16_t h_start_width, uint16_t h_sync_width,
-                           uint16_t h_end_width, uint16_t v_start_width,
-                           uint16_t v_sync_width, uint16_t v_end_width,
-                           uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
+ int ipu_init_sync_panel(int disp, uint32_t pixel_clk,
+                       uint16_t width, uint16_t height,
+                       uint32_t pixel_fmt,
+                       uint16_t h_start_width, uint16_t h_sync_width,
+                       uint16_t h_end_width, uint16_t v_start_width,
+                       uint16_t v_sync_width, uint16_t v_end_width,
+                       uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
  {
        uint32_t reg;
        uint32_t di_gen, vsync_cnt;
        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*/
+               if (!(g_di1_tvout && (disp == 1))) { /* don't round div for tvout */
                        /*
                         * Set the  PLL to be an even multiple
                         * of the pixel clock.
                                rounded_pixel_clk =
                                        clk_round_rate(g_pixel_clk[disp],
                                                pixel_clk);
-                               div  = clk_get_rate(di_parent) /
-                                       rounded_pixel_clk;
-                               if (div % 2)
-                                       div++;
-                               if (clk_get_rate(di_parent) != div *
-                                       rounded_pixel_clk)
-                                       clk_set_rate(di_parent,
-                                               div * rounded_pixel_clk);
-                               udelay(10000);
-                               clk_set_rate(g_di_clk[disp],
-                                       2 * rounded_pixel_clk);
-                               udelay(10000);
+                               if (di_parent != NULL) {
+                                       div  = clk_get_rate(di_parent) /
+                                               rounded_pixel_clk;
+                                       if (div % 2)
+                                               div++;
+                                       if (clk_get_rate(di_parent) != div *
+                                               rounded_pixel_clk)
+                                               clk_set_rate(di_parent,
+                                                       div * rounded_pixel_clk);
+                                       udelay(10000);
+                                       clk_set_rate(g_di_clk[disp],
+                                               2 * rounded_pixel_clk);
+                                       udelay(10000);
+                               }
                        }
                }
                clk_set_parent(g_pixel_clk[disp], g_ldb_clk);
                if (clk_get_usecount(g_pixel_clk[disp]) != 0)
                        clk_set_parent(g_pixel_clk[disp], g_ipu_clk);
        }
-       rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk);
-       clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
-       udelay(5000);
-       /* Get integer portion of divider */
-       div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) /
-               rounded_pixel_clk;
-       ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
+       /* Enable for a divide by 2 clock change. */
+       reg = __raw_readl(IPU_PM);
+       reg &= ~(0x7f << 7);
+       reg |= 0x20 << 7;
+       reg &= ~(0x7f << 23);
+       reg |= 0x20 << 23;
+       __raw_writel(reg, IPU_PM);
+       di_gen = 0;
+       if (pixel_fmt != IPU_PIX_FMT_LVDS666 &&
+                       pixel_fmt != IPU_PIX_FMT_LVDS888) {
+               rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk);
+               clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
+               udelay(5000);
+               /* Get integer portion of divider */
+               div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) /
+                       rounded_pixel_clk;
+               ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
+       } else {
+               rounded_pixel_clk = clk_get_rate(clk_get_parent(g_pixel_clk[disp]));
+               clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
+               div = 1;
+               ipu_di_data_wave_config(disp, SYNC_WAVE, 0, 0);
+               di_gen |= (6 << 24);
+               di_gen |= DI_GEN_DI_CLK_EXT;
+       }
        ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
  
        map = ipu_pixfmt_to_map(pixel_fmt);
        if (map < 0) {
-               debug("IPU_DISP: No MAP\n");
-               return -EINVAL;
+               printf("IPU_DISP: No MAP for pixel format: %c%c%c%c\n",
+                       pixel_fmt, pixel_fmt >> 8, pixel_fmt >> 16,
+                       pixel_fmt >> 24);
+               return map;
        }
  
-       di_gen = __raw_readl(DI_GENERAL(disp));
        if (sig.interlaced) {
                /* Setup internal HSYNC waveform */
                ipu_di_sync_config(
                /* set gentime select and tag sel */
                reg = __raw_readl(DI_SW_GEN1(disp, 9));
                reg &= 0x1FFFFFFF;
-               reg |= (3 - 1)<<29 | 0x00008000;
+               reg |= ((3 - 1) << 29) | 0x00008000;
                __raw_writel(reg, DI_SW_GEN1(disp, 9));
  
                __raw_writel(v_total / 2 - 1, DI_SCR_CONF(disp));
                __raw_writel(0, DI_STP_REP(disp, 7));
                __raw_writel(0, DI_STP_REP(disp, 9));
  
+               h_total = ((width + h_start_width + h_sync_width) / 2) - 2;
+               ipu_di_sync_config(disp, 6, 1, 0, 2, DI_SYNC_CLK, h_total,
+                               DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE,
+                               DI_SYNC_NONE, 0, 0);
                /* Init template microcode */
                if (disp) {
-                  ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
-                  ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
-                  ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+                       ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
                } else {
-                  ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
-                  ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
-                  ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+                       ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
                }
  
                if (sig.Hsync_pol)
                if (sig.Vsync_pol)
                        di_gen |= DI_GEN_POLARITY_3;
  
 -              if (sig.clk_pol)
 +              if (!sig.clk_pol)
                        di_gen |= DI_GEN_POL_CLK;
  
+               /* Set the clock to stop at counter 6. */
+               di_gen |= 0x6000000;
        }
  
        __raw_writel(di_gen, DI_GENERAL(disp));
  
-       __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
-                       0x00000002, DI_SYNC_AS_GEN(disp));
+       if (sig.interlaced)
+               __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
+                               0x00000002, DI_SYNC_AS_GEN(disp));
+       else
+               __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET),
+                               DI_SYNC_AS_GEN(disp));
  
        reg = __raw_readl(DI_POL(disp));
        reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
   *
   * @return      Returns 0 on success or negative error code on fail
   */
- int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
+ int ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
                                  uint8_t alpha)
  {
+       int ret;
        uint32_t reg;
  
        unsigned char bg_chan;
        else
                bg_chan = 0;
  
-       if (!g_ipu_clk_enabled)
-               clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
  
        if (bg_chan) {
                reg = __raw_readl(DP_COM_CONF());
        reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
        __raw_writel(reg, IPU_SRM_PRI2);
  
-       if (!g_ipu_clk_enabled)
-               clk_disable(g_ipu_clk);
+       clk_disable(g_ipu_clk);
  
        return 0;
  }
   *
   * @return      Returns 0 on success or negative error code on fail
   */
- int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
+ int ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
                               uint32_t color_key)
  {
+       int ret;
        uint32_t reg;
        int y, u, v;
        int red, green, blue;
                (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)))
                return -EINVAL;
  
-       if (!g_ipu_clk_enabled)
-               clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
  
        color_key_4rgb = 1;
        /* Transform color key from rgb to yuv if CSC is enabled */
        reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
        __raw_writel(reg, IPU_SRM_PRI2);
  
-       if (!g_ipu_clk_enabled)
-               clk_disable(g_ipu_clk);
+       clk_disable(g_ipu_clk);
  
        return 0;
  }
diff --combined drivers/video/ipu_regs.h
index c2c134a7de0738beca41c7b871c0869d5f6fe031,07626941dfd92db8db299fe287d56de7e526557d..ea0cf4141bd1eb265594ffba13cd6f3a36dd511b
@@@ -4,9 -4,9 +4,9 @@@
   * (C) Copyright 2010
   * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   *
-  * Linux IPU driver for MX51:
+  * Linux IPU driver:
   *
-  * (C) Copyright 2005-2009 Freescale Semiconductor, Inc.
+  * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
  #ifndef __IPU_REGS_INCLUDED__
  #define __IPU_REGS_INCLUDED__
  
+ #include <asm/arch/imx-regs.h>
  #define IPU_DISP0_BASE                0x00000000
  #define IPU_MCU_T_DEFAULT     8
- #define IPU_DISP1_BASE                (IPU_MCU_T_DEFAULT << 25)
+ #define IPU_DISP1_BASE                (gd->arch.ipu_hw_rev < IPUV3_HW_REV_IPUV3H ?    \
+                               (IPU_MCU_T_DEFAULT << 25) :             \
+                               0x00000000)
+ #define IPUV3DEX_REG_BASE     0x1E000000
+ #define IPUV3M_REG_BASE               0x1E000000
+ #define IPUV3H_REG_BASE               0x00200000
  #define IPU_CM_REG_BASE               0x00000000
  #define IPU_STAT_REG_BASE     0x00000200
  #define IPU_IDMAC_REG_BASE    0x00008000
  #define IPU_SMFC_REG_BASE     0x00050000
  #define IPU_DC_REG_BASE               0x00058000
  #define IPU_DMFC_REG_BASE     0x00060000
- #define IPU_VDI_REG_BASE      0x00680000
- #if defined(CONFIG_MX51) || defined(CONFIG_MX53)
- #define IPU_CPMEM_REG_BASE    0x01000000
- #define IPU_LUT_REG_BASE      0x01020000
- #define IPU_SRM_REG_BASE      0x01040000
- #define IPU_TPM_REG_BASE      0x01060000
- #define IPU_DC_TMPL_REG_BASE  0x01080000
- #define IPU_ISP_TBPR_REG_BASE 0x010C0000
- #elif defined(CONFIG_MX6)
- #define IPU_CPMEM_REG_BASE    0x00100000
- #define IPU_LUT_REG_BASE      0x00120000
- #define IPU_SRM_REG_BASE      0x00140000
- #define IPU_TPM_REG_BASE      0x00160000
- #define IPU_DC_TMPL_REG_BASE  0x00180000
- #define IPU_ISP_TBPR_REG_BASE 0x001C0000
- #endif
- #define IPU_CTRL_BASE_ADDR    (IPU_SOC_BASE_ADDR + IPU_SOC_OFFSET)
+ #define IPU_VDI_REG_BASE      0x00068000
+ #define IPU_CPMEM_REG_BASE    (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00100000 :                            \
+                               0x01000000)
+ #define IPU_LUT_REG_BASE      (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00120000 :                            \
+                               0x01020000)
+ #define IPU_SRM_REG_BASE      (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00140000 :                            \
+                               0x01040000)
+ #define IPU_TPM_REG_BASE      (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00160000 :                            \
+                               0x01060000)
+ #define IPU_DC_TMPL_REG_BASE  (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00180000 :                            \
+                               0x01080000)
+ #define IPU_ISP_TBPR_REG_BASE (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x001C0000 :                            \
+                               0x010C0000)
+ #define IPU_DISP_REG_BASE_ADDR        (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               IPU_SOC_BASE_ADDR + IPUV3H_REG_BASE :   \
+                               IPU_SOC_BASE_ADDR + IPUV3M_REG_BASE)
  
  extern u32 *ipu_dc_tmpl_reg;
+ extern struct clk *g_ipu_clk;
+ extern struct clk *g_ldb_clk;
+ extern struct clk *g_di_clk[2];
+ extern struct clk *g_pixel_clk[2];
+ extern int g_ipu_clk_enabled;
+ extern unsigned char g_dc_di_assignment[];
  
  #define DC_EVT_NF             0
  #define DC_EVT_NL             1
@@@ -91,7 -112,7 +112,7 @@@ enum 
        DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
        DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
  
-       DI_GEN_DI_CLK_EXT = 0x100000,
+       DI_GEN_DI_CLK_EXT = 0x00100000,
        DI_GEN_POLARITY_1 = 0x00000001,
        DI_GEN_POLARITY_2 = 0x00000002,
        DI_GEN_POLARITY_3 = 0x00000004,
        DI_GEN_POLARITY_6 = 0x00000020,
        DI_GEN_POLARITY_7 = 0x00000040,
        DI_GEN_POLARITY_8 = 0x00000080,
-       DI_GEN_POL_CLK = 0x20000,
+       DI_GEN_POL_CLK    = 0x00020000,
  
        DI_POL_DRDY_DATA_POLARITY = 0x00000080,
        DI_POL_DRDY_POLARITY_15 = 0x00000010,
@@@ -171,7 -192,7 +192,7 @@@ struct ipu_cm 
        u32 gpr;
        u32 reserved0[26];
        u32 ch_db_mode_sel[2];
 -      u32 reserved1[16];
 +      u32 reserved1[4];
        u32 alt_ch_db_mode_sel[2];
        u32 reserved2[2];
        u32 ch_trb_mode_sel[2];
@@@ -188,7 -209,7 +209,7 @@@ struct ipu_idmac 
        u32 sub_addr[5];
        u32 bndm_en[2];
        u32 sc_cord[2];
 -      u32 reserved[45];
 +      u32 reserved[44];
        u32 ch_busy[2];
  };
  
@@@ -297,7 -318,7 +318,7 @@@ struct ipu_dmfc 
        u32 stat;
  };
  
- #define IPU_CM_REG            ((struct ipu_cm *)(IPU_CTRL_BASE_ADDR + \
+ #define IPU_CM_REG            ((struct ipu_cm *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_CM_REG_BASE))
  #define IPU_CONF              (&IPU_CM_REG->conf)
  #define IPU_SRM_PRI1          (&IPU_CM_REG->srm_pri1)
  #define IPU_FS_DISP_FLOW1     (&IPU_CM_REG->fs_disp_flow[0])
  #define IPU_DISP_GEN          (&IPU_CM_REG->disp_gen)
  #define IPU_MEM_RST           (&IPU_CM_REG->mem_rst)
+ #define IPU_PM                        (&IPU_CM_REG->pm)
  #define IPU_GPR                       (&IPU_CM_REG->gpr)
- #define IPU_CHA_DB_MODE_SEL(ch)       (&IPU_CM_REG->ch_db_mode_sel[ch / 32])
+ #define IPU_CHA_DB_MODE_SEL(ch)       (&IPU_CM_REG->ch_db_mode_sel[(ch) / 32])
  
- #define IPU_STAT              ((struct ipu_stat *)(IPU_CTRL_BASE_ADDR + \
+ #define IPU_STAT              ((struct ipu_stat *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_STAT_REG_BASE))
- #define IPU_CHA_CUR_BUF(ch)   (&IPU_STAT->cur_buf[ch / 32])
- #define IPU_CHA_BUF0_RDY(ch)  (&IPU_STAT->ch_buf0_rdy[ch / 32])
- #define IPU_CHA_BUF1_RDY(ch)  (&IPU_STAT->ch_buf1_rdy[ch / 32])
 +#define IPU_INT_STAT(n)               (&IPU_STAT->int_stat[(n) - 1])
+ #define IPU_CHA_CUR_BUF(ch)   (&IPU_STAT->cur_buf[(ch) / 32])
+ #define IPU_CHA_BUF0_RDY(ch)  (&IPU_STAT->ch_buf0_rdy[(ch) / 32])
+ #define IPU_CHA_BUF1_RDY(ch)  (&IPU_STAT->ch_buf1_rdy[(ch) / 32])
 +#define IPUIRQ_2_STATREG(irq) (IPU_INT_STAT(1) + ((irq) / 32))
 +#define IPUIRQ_2_MASK(irq)    (1UL << ((irq) & 0x1F))
  
  #define IPU_INT_CTRL(n)               (&IPU_CM_REG->int_ctrl[(n) - 1])
  
- #define IDMAC_REG             ((struct ipu_idmac *)(IPU_CTRL_BASE_ADDR + \
+ #define IDMAC_REG             ((struct ipu_idmac *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_IDMAC_REG_BASE))
  #define IDMAC_CONF            (&IDMAC_REG->conf)
- #define IDMAC_CHA_EN(ch)      (&IDMAC_REG->ch_en[ch / 32])
- #define IDMAC_CHA_PRI(ch)     (&IDMAC_REG->ch_pri[ch / 32])
+ #define IDMAC_CHA_EN(ch)      (&IDMAC_REG->ch_en[(ch) / 32])
+ #define IDMAC_CHA_PRI(ch)     (&IDMAC_REG->ch_pri[(ch) / 32])
+ #define IDMAC_WM_EN(ch)               (&IDMAC_REG->wm_en[(ch) / 32])
+ #define DI_REG(di)            ((struct ipu_di *)(IPU_DISP_REG_BASE_ADDR + \
+                                       (((di) == 1) ? IPU_DI1_REG_BASE : \
+                                       IPU_DI0_REG_BASE)))
  
- #define DI_REG(di)            ((struct ipu_di *)(IPU_CTRL_BASE_ADDR + \
-                               ((di == 1) ? IPU_DI1_REG_BASE : \
-                               IPU_DI0_REG_BASE)))
  #define DI_GENERAL(di)                (&DI_REG(di)->general)
  #define DI_BS_CLKGEN0(di)     (&DI_REG(di)->bs_clkgen0)
  #define DI_BS_CLKGEN1(di)     (&DI_REG(di)->bs_clkgen1)
  
- #define DI_SW_GEN0(di, gen)   (&DI_REG(di)->sw_gen0[gen - 1])
- #define DI_SW_GEN1(di, gen)   (&DI_REG(di)->sw_gen1[gen - 1])
- #define DI_STP_REP(di, gen)   (&DI_REG(di)->stp_rep[(gen - 1) / 2])
+ #define DI_SW_GEN0(di, gen)   (&DI_REG(di)->sw_gen0[(gen) - 1])
+ #define DI_SW_GEN1(di, gen)   (&DI_REG(di)->sw_gen1[(gen) - 1])
+ #define DI_STP_REP(di, gen)   (&DI_REG(di)->stp_rep[((gen) - 1) / 2])
  #define DI_SYNC_AS_GEN(di)    (&DI_REG(di)->sync_as)
  #define DI_DW_GEN(di, gen)    (&DI_REG(di)->dw_gen[gen])
- #define DI_DW_SET(di, gen, set)       (&DI_REG(di)->dw_set[gen + 12 * set])
+ #define DI_DW_SET(di, gen, set)       (&DI_REG(di)->dw_set[(gen) + 12 * set])
  #define DI_POL(di)            (&DI_REG(di)->pol)
  #define DI_SCR_CONF(di)               (&DI_REG(di)->scr_conf)
  
- #define DMFC_REG              ((struct ipu_dmfc *)(IPU_CTRL_BASE_ADDR + \
+ #define DMFC_REG              ((struct ipu_dmfc *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DMFC_REG_BASE))
  #define DMFC_WR_CHAN          (&DMFC_REG->wr_chan)
  #define DMFC_WR_CHAN_DEF      (&DMFC_REG->wr_chan_def)
  #define DMFC_GENERAL1         (&DMFC_REG->general[0])
  #define DMFC_IC_CTRL          (&DMFC_REG->ic_ctrl)
  
- #define DC_REG                        ((struct ipu_dc *)(IPU_CTRL_BASE_ADDR + \
+ #define DC_REG                        ((struct ipu_dc *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DC_REG_BASE))
- #define DC_MAP_CONF_PTR(n)    (&DC_REG->dc_map_ptr[n / 2])
- #define DC_MAP_CONF_VAL(n)    (&DC_REG->dc_map_val[n / 2])
+ #define DC_MAP_CONF_PTR(n)    (&DC_REG->dc_map_ptr[(n) / 2])
+ #define DC_MAP_CONF_VAL(n)    (&DC_REG->dc_map_val[(n) / 2])
  
+ DECLARE_GLOBAL_DATA_PTR;
  
  static inline struct ipu_dc_ch *dc_ch_offset(int ch)
  {
                printf("%s: invalid channel %d\n", __func__, ch);
                return NULL;
        }
  }
  
- #define DC_RL_CH(ch, evt)     (&dc_ch_offset(ch)->rl[evt / 2])
+ #define DC_RL_CH(ch, evt)     (&dc_ch_offset(ch)->rl[(evt) / 2])
  
  #define DC_WR_CH_CONF(ch)     (&dc_ch_offset(ch)->wr_ch_conf)
  #define DC_WR_CH_ADDR(ch)     (&dc_ch_offset(ch)->wr_ch_addr)
  #define DP_ASYNC0 0x60
  #define DP_ASYNC1 0xBC
  
- #define DP_REG                        ((struct ipu_dp *)(IPU_CTRL_BASE_ADDR + \
+ #define DP_REG                        ((struct ipu_dp *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DP_REG_BASE))
  #define DP_COM_CONF()         (&DP_REG->com_conf_sync)
  #define DP_GRAPH_WIND_CTRL()  (&DP_REG->graph_wind_ctrl_sync)
  #define DP_CSC_1()            (&DP_REG->csc_sync[1])
  
  /* DC template opcodes */
- #define WROD(lf)              (0x18 | (lf << 1))
+ #define WROD(lf)              (0x18 | ((lf) << 1))
  
  #endif
index 1fa95314fc4621857114bcef2e98e50a60f163b7,017f6220d10acc01a16b3ebea69ba1b738afebb9..cd95abab837064a5616649a6b85c4e255062a27b
@@@ -4,37 -4,41 +4,42 @@@
   * (C) Copyright 2010
   * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   *
-  * MX51 Linux framebuffer:
+  * IPUv3 Linux framebuffer:
   *
-  * (C) Copyright 2004-2010 Freescale Semiconductor, Inc.
+  * (C) Copyright 2004-2011 Freescale Semiconductor, Inc.
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
  
+ /* #define DEBUG */
  #include <common.h>
  #include <asm/errno.h>
 +#include <asm/global_data.h>
  #include <linux/string.h>
  #include <linux/list.h>
  #include <linux/fb.h>
  #include <asm/io.h>
  #include <malloc.h>
+ #include <lcd.h>
+ #include <ipu.h>
  #include <video_fb.h>
- #include "videomodes.h"
- #include "ipu.h"
- #include "mxcfb.h"
+ #include <mxcfb.h>
  #include "ipu_regs.h"
+ #include "videomodes.h"
  
  DECLARE_GLOBAL_DATA_PTR;
  
  static int mxcfb_map_video_memory(struct fb_info *fbi);
  static int mxcfb_unmap_video_memory(struct fb_info *fbi);
  
- /* graphics setup */
- static GraphicDevice panel;
- static struct fb_videomode const *gmode;
- static uint8_t gdisp;
- static uint32_t gpixfmt;
+ void lcd_initcolregs(void)
+ {
+ }
+ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+ {
+ }
  
  static void fb_videomode_to_var(struct fb_var_screeninfo *var,
                         const struct fb_videomode *mode)
@@@ -108,6 -112,8 +113,8 @@@ static uint32_t bpp_to_pixfmt(struct fb
        case 16:
                pixfmt = IPU_PIX_FMT_RGB565;
                break;
+       case 8:
+               pixfmt = IPU_PIX_FMT_GENERIC;
        }
        return pixfmt;
  }
@@@ -136,7 -142,7 +143,7 @@@ static int mxcfb_set_fix(struct fb_inf
  static int setup_disp_channel1(struct fb_info *fbi)
  {
        ipu_channel_params_t params;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
  
        memset(&params, 0, sizeof(params));
        params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
  static int setup_disp_channel2(struct fb_info *fbi)
  {
        int retval = 0;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
  
        mxc_fbi->cur_ipu_buf = 1;
        if (mxc_fbi->alpha_chan_en)
  
        fbi->var.xoffset = fbi->var.yoffset = 0;
  
-       debug("%s: %x %d %d %d %lx %lx\n",
+       debug("%s: ch: %08x xres: %d yres: %d line_length: %d mem: %08lx .. %08lx\n",
                __func__,
                mxc_fbi->ipu_ch,
                fbi->var.xres,
                fbi->fix.line_length,
                fbi->fix.smem_start,
                fbi->fix.smem_start +
-               (fbi->fix.line_length * fbi->var.yres));
+               (fbi->fix.line_length * fbi->var.yres) - 1);
  
        retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
                                         bpp_to_pixfmt(fbi),
@@@ -213,7 -219,7 +220,7 @@@ static int mxcfb_set_par(struct fb_inf
        int retval = 0;
        u32 mem_len;
        ipu_di_signal_cfg_t sig_cfg;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
        uint32_t out_pixel_fmt;
  
        ipu_disable_channel(mxc_fbi->ipu_ch);
        if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
                sig_cfg.clkidle_en = 1;
  
-       debug("pixclock = %lu Hz\n", PICOS2KHZ(fbi->var.pixclock) * 1000UL);
+       debug("pixclock = %lu.%03lu MHz\n",
+               PICOS2KHZ(fbi->var.pixclock) / 1000,
+               PICOS2KHZ(fbi->var.pixclock) % 1000);
  
-       if (ipu_init_sync_panel(mxc_fbi->ipu_di,
+       retval = ipu_init_sync_panel(mxc_fbi->ipu_di,
                                (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
                                fbi->var.xres, fbi->var.yres,
                                out_pixel_fmt,
                                fbi->var.upper_margin,
                                fbi->var.vsync_len,
                                fbi->var.lower_margin,
-                               0, sig_cfg) != 0) {
-               puts("mxcfb: Error initializing panel.\n");
-               return -EINVAL;
+                               0, sig_cfg);
+       if (retval != 0) {
+               printf("mxc_ipuv3_fb: Error %d initializing panel\n", retval);
+               return retval;
        }
  
        retval = setup_disp_channel2(fbi);
@@@ -401,27 -410,22 +411,27 @@@ static int mxcfb_map_video_memory(struc
                fbi->fix.smem_len = fbi->var.yres_virtual *
                                    fbi->fix.line_length;
        }
-       fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
-                                           fbi->fix.smem_len);
-       fbi->fix.smem_start = (unsigned long)fbi->screen_base;
-       if (fbi->screen_base == 0) {
++
 +      fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN);
 -              fbi->screen_base = malloc(fbi->fix.smem_len);
+       if (gd->fb_base)
+               fbi->screen_base = (void *)gd->fb_base;
+       else
++              fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
++                                              fbi->fix.smem_len);
+       if (fbi->screen_base == NULL) {
                puts("Unable to allocate framebuffer memory\n");
                fbi->fix.smem_len = 0;
-               fbi->fix.smem_start = 0;
                return -EBUSY;
        }
+       fbi->fix.smem_start = (unsigned long)fbi->screen_base;
  
        debug("allocated fb @ paddr=0x%08X, size=%d.\n",
                (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  
        fbi->screen_size = fbi->fix.smem_len;
  
-       /* Clear the screen */
-       memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
 +      gd->fb_base = fbi->fix.smem_start;
 +
        return 0;
  }
  
@@@ -444,17 -448,14 +454,14 @@@ static int mxcfb_unmap_video_memory(str
   */
  static struct fb_info *mxcfb_init_fbinfo(void)
  {
- #define BYTES_PER_LONG 4
- #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
        struct fb_info *fbi;
        struct mxcfb_info *mxcfbi;
-       char *p;
-       int size = sizeof(struct mxcfb_info) + PADDING +
+       void *p;
+       int size = ALIGN(sizeof(struct mxcfb_info), sizeof(long)) +
                sizeof(struct fb_info);
  
-       debug("%s: %d %d %d %d\n",
+       debug("%s: %d %d %d\n",
                __func__,
-               PADDING,
                size,
                sizeof(struct mxcfb_info),
                sizeof(struct fb_info));
  
        memset(p, 0, size);
  
-       fbi = (struct fb_info *)p;
-       fbi->par = p + sizeof(struct fb_info) + PADDING;
+       fbi = p;
+       fbi->par = p + ALIGN(sizeof(struct fb_info), sizeof(long));
  
-       mxcfbi = (struct mxcfb_info *)fbi->par;
-       debug("Framebuffer structures at: fbi=0x%x mxcfbi=0x%x\n",
-               (unsigned int)fbi, (unsigned int)mxcfbi);
+       mxcfbi = fbi->par;
+       debug("Framebuffer structures at: fbi=%p mxcfbi=%p\n",
+               fbi, mxcfbi);
  
        fbi->var.activate = FB_ACTIVATE_NOW;
  
  
  /*
   * 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.
   *
   * @return      Appropriate error code to the kernel common code
   */
- static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
-                       struct fb_videomode const *mode)
+ static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode, int di)
  {
        struct fb_info *fbi;
        struct mxcfb_info *mxcfbi;
-       int ret = 0;
  
        /*
         * Initialize FB structures
         */
        fbi = mxcfb_init_fbinfo();
-       if (!fbi) {
-               ret = -ENOMEM;
-               goto err0;
-       }
-       mxcfbi = (struct mxcfb_info *)fbi->par;
+       if (!fbi)
+               return -ENOMEM;
+       mxcfbi = fbi->par;
  
        if (!g_dp_in_use) {
                mxcfbi->ipu_ch = MEM_BG_SYNC;
                mxcfbi->blank = FB_BLANK_POWERDOWN;
        }
  
-       mxcfbi->ipu_di = disp;
+       mxcfbi->ipu_di = di;
  
        ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80);
        ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0);
        mxcfb_info[mxcfbi->ipu_di] = fbi;
  
        /* Need dummy values until real panel is configured */
+       fbi->var.xres = panel_info.vl_col;
+       fbi->var.yres = panel_info.vl_row;
  
        mxcfbi->ipu_di_pix_fmt = interface_pix_fmt;
        fb_videomode_to_var(&fbi->var, mode);
-       fbi->var.bits_per_pixel = 16;
+       fbi->var.bits_per_pixel = NBITS(panel_info.vl_bpix);
        fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8);
        fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length;
  
  
        mxcfb_set_par(fbi);
  
-       panel.winSizeX = mode->xres;
-       panel.winSizeY = mode->yres;
-       panel.plnSizeX = mode->xres;
-       panel.plnSizeY = mode->yres;
+       lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
  
-       panel.frameAdrs = (u32)fbi->screen_base;
-       panel.memSize = fbi->screen_size;
-       panel.gdfBytesPP = 2;
-       panel.gdfIndex = GDF_16BIT_565RGB;
+       debug("MXC IPUV3 configured\n"
+               "XRES = %d YRES = %d BitsXpixel = %d\n",
+               panel_info.vl_col,
+               panel_info.vl_row,
+               panel_info.vl_bpix);
  
        ipu_dump_registers();
  
        return 0;
+ }
  
- err0:
-       return ret;
+ ulong calc_fbsize(void)
+ {
+       return (panel_info.vl_col * panel_info.vl_row *
+               NBITS(panel_info.vl_bpix)) / 8;
  }
  
  void ipuv3_fb_shutdown(void)
                        ipu_uninit_channel(mxc_fbi->ipu_ch);
                }
        }
+       clk_enable(g_ipu_clk);
        for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
                __raw_writel(__raw_readl(&stat->int_stat[i]),
                             &stat->int_stat[i]);
        }
+       clk_disable(g_ipu_clk);
  }
  
- void *video_hw_init(void)
+ int ipuv3_fb_init(struct fb_videomode *mode, int di, unsigned int interface_pix_fmt,
+               ipu_di_clk_parent_t di_clk_parent, unsigned long di_clk_val, int bpp)
  {
        int ret;
  
-       ret = ipu_probe();
-       if (ret)
-               puts("Error initializing IPU\n");
-       ret = mxcfb_probe(gpixfmt, gdisp, gmode);
-       debug("Framebuffer at 0x%x\n", (unsigned int)panel.frameAdrs);
-       return (void *)&panel;
- }
- void video_set_lut(unsigned int index, /* color number */
-                       unsigned char r,    /* red */
-                       unsigned char g,    /* green */
-                       unsigned char b     /* blue */
-                       )
- {
-       return;
- }
+       default_bpp = bpp;
  
- int ipuv3_fb_init(struct fb_videomode const *mode,
-                 uint8_t disp,
-                 uint32_t pixfmt)
- {
-       gmode = mode;
-       gdisp = disp;
-       gpixfmt = pixfmt;
+       ret = ipu_probe(di, di_clk_parent, di_clk_val);
+       if (ret) {
+               printf("Error initializing IPU\n");
+               return ret;
+       }
  
-       return 0;
+       return mxcfb_probe(interface_pix_fmt, mode, di);
  }
diff --combined drivers/video/mxsfb.c
index 03b0f88acfaa26cf930bbe8d6390b1b731de32b8,f7b5827388d877f1e5abac41db6187a794d35952..68293d2b75dcc019d56ca2e98e8864ed1088759c
@@@ -8,6 -8,7 +8,7 @@@
  #include <common.h>
  #include <malloc.h>
  #include <video_fb.h>
+ #include <mxcfb.h>
  
  #include <asm/arch/imx-regs.h>
  #include <asm/arch/clock.h>
  #include <asm/errno.h>
  #include <asm/io.h>
  
 +#include <asm/imx-common/dma.h>
 +
  #include "videomodes.h"
  
  #define       PS2KHZ(ps)      (1000000000UL / (ps))
  
+ DECLARE_GLOBAL_DATA_PTR;
  static GraphicDevice panel;
 +struct mxs_dma_desc desc;
 +
 +/**
 + * mxsfb_system_setup() - Fine-tune LCDIF configuration
 + *
 + * This function is used to adjust the LCDIF configuration. This is usually
 + * needed when driving the controller in System-Mode to operate an 8080 or
 + * 6800 connected SmartLCD.
 + */
 +__weak void mxsfb_system_setup(void)
 +{
 +}
  
  /*
   * DENX M28EVK:
   * Freescale mx23evk/mx28evk with a Seiko 4.3'' WVGA panel:
   * setenv videomode
   * video=ctfb:x:800,y:480,depth:24,mode:0,pclk:29851,
-  *     le:89,ri:164,up:23,lo:10,hs:10,vs:10,sync:0,vmode:0
+  *     le:89,ri:164,up:23,lo:10,hs:10,vs:10,sync:0,vmode:0
   */
  
  static void mxs_lcd_init(GraphicDevice *panel,
                        struct ctfb_res_modes *mode, int bpp)
  {
        struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
-       uint32_t word_len = 0, bus_width = 0;
-       uint8_t valid_data = 0;
+       uint32_t word_len, bus_width;
+       uint8_t valid_data;
+       uint32_t vctrl0 = 0;
  
        /* Kick in the LCDIF clock */
        mxs_set_lcdclk(PS2KHZ(mode->pixclock));
@@@ -81,6 -71,9 +85,9 @@@
                bus_width = LCDIF_CTRL_LCD_DATABUS_WIDTH_8BIT;
                valid_data = 0xf;
                break;
+       default:
+               printf("Invalid color depth: %d\n", bpp);
+               hang();
        }
  
        writel(bus_width | word_len | LCDIF_CTRL_DOTCLK_MODE |
  
        writel(valid_data << LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET,
                &regs->hw_lcdif_ctrl1);
 +
 +      mxsfb_system_setup();
 +
        writel((mode->yres << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) | mode->xres,
                &regs->hw_lcdif_transfer_count);
  
-       writel(LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_ENABLE_POL |
+       if (!(mode->sync & FB_SYNC_OE_LOW_ACT))
+               vctrl0 |= LCDIF_VDCTRL0_ENABLE_POL;
+       if (mode->sync & FB_SYNC_CLK_LAT_FALL)
+               vctrl0 |= LCDIF_VDCTRL0_DOTCLK_POL;
+       if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+               vctrl0 |= LCDIF_VDCTRL0_HSYNC_POL;
+       if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+               vctrl0 |= LCDIF_VDCTRL0_VSYNC_POL;
+       writel(vctrl0 | LCDIF_VDCTRL0_ENABLE_PRESENT |
                LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
                LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
                mode->vsync_len, &regs->hw_lcdif_vdctrl0);
        /* Flush FIFO first */
        writel(LCDIF_CTRL1_FIFO_CLEAR, &regs->hw_lcdif_ctrl1_set);
  
 +#ifndef CONFIG_VIDEO_MXS_MODE_SYSTEM
        /* Sync signals ON */
        setbits_le32(&regs->hw_lcdif_vdctrl4, LCDIF_VDCTRL4_SYNC_SIGNALS_ON);
 +#endif
  
        /* FIFO cleared */
        writel(LCDIF_CTRL1_FIFO_CLEAR, &regs->hw_lcdif_ctrl1_clr);
@@@ -135,7 -135,6 +154,6 @@@ void *video_hw_init(void
  {
        int bpp = -1;
        char *penv;
-       void *fb;
        struct ctfb_res_modes mode;
  
        puts("Video: ");
  
        panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP;
  
-       /* Allocate framebuffer */
-       fb = memalign(ARCH_DMA_MINALIGN,
-                     roundup(panel.memSize, ARCH_DMA_MINALIGN));
-       if (!fb) {
-               printf("MXSFB: Error allocating framebuffer!\n");
-               return NULL;
-       }
-       /* Wipe framebuffer */
-       memset(fb, 0, panel.memSize);
-       panel.frameAdrs = (u32)fb;
+       panel.frameAdrs = gd->fb_base;
  
        printf("%s\n", panel.modeIdent);
  
        /* Start framebuffer */
        mxs_lcd_init(&panel, &mode, bpp);
  
 -      return &panel;
 +#ifdef CONFIG_VIDEO_MXS_MODE_SYSTEM
 +      /*
 +       * If the LCD runs in system mode, the LCD refresh has to be triggered
 +       * manually by setting the RUN bit in HW_LCDIF_CTRL register. To avoid
 +       * having to set this bit manually after every single change in the
 +       * framebuffer memory, we set up specially crafted circular DMA, which
 +       * sets the RUN bit, then waits until it gets cleared and repeats this
 +       * infinitelly. This way, we get smooth continuous updates of the LCD.
 +       */
 +      struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
 +
 +      memset(&desc, 0, sizeof(struct mxs_dma_desc));
 +      desc.address = (dma_addr_t)&desc;
 +      desc.cmd.data = MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
 +                      MXS_DMA_DESC_WAIT4END |
 +                      (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
 +      desc.cmd.pio_words[0] = readl(&regs->hw_lcdif_ctrl) | LCDIF_CTRL_RUN;
 +      desc.cmd.next = (uint32_t)&desc.cmd;
 +
 +      /* Execute the DMA chain. */
 +      mxs_dma_circ_start(MXS_DMA_CHANNEL_AHB_APBH_LCDIF, &desc);
 +#endif
 +
 +      return (void *)&panel;
  }
diff --combined drivers/watchdog/Kconfig
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,0000000000000000000000000000000000000000..052e24f6cde67a615bfd9035fa1862f35ebcee74
mode 100644,000000..100644
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++config HW_WATCHDOG
++      bool "Generic SoC specific watchdog support"
++      depends on !MX6
++
++config IMX_WATCHDOG
++      bool "Freescale i.MX watchdog support"
++      depends on MX31 || MX35 || MX5 || MX6 || VF610 || LS102XA
index 1dc0f5aa101e4fabf9710563ce37cb21d1f9faf9,7e255ce8aef987daf37f52e0f00d41292162946a..efad1432d607392584659efc5b822a9c5ce8473b
@@@ -5,14 -5,34 +5,12 @@@
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
- obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
- obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
- ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610 ls102xa))
- obj-y += imx_watchdog.o
 -include $(TOPDIR)/config.mk
 -
 -LIB   := $(obj)libwatchdog.o
 -
 -COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
 -COBJS-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
 -ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610))
 -COBJS-y += imx_watchdog.o
--endif
- obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
- obj-$(CONFIG_S5P)               += s5p_wdt.o
- obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
- obj-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
- obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
- obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
 -COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
 -COBJS-$(CONFIG_S5P)               += s5p_wdt.o
 -COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
 -COBJS-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
 -
 -COBJS := $(COBJS-y)
 -SRCS  := $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -
 -all:  $(LIB)
 -
 -$(LIB):       $(obj).depend $(OBJS)
 -      $(call cmd_link_o_target, $(OBJS))
 -
 -#########################################################################
 -
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
++obj-$(CONFIG_AT91SAM9_WATCHDOG)               += at91sam9_wdt.o
++obj-$(CONFIG_BFIN_WATCHDOG)           += bfin_wdt.o
++obj-$(CONFIG_DESIGNWARE_WATCHDOG)     += designware_wdt.o
++obj-$(CONFIG_FTWDT010_WATCHDOG)               += ftwdt010_wdt.o
++obj-$(CONFIG_IMX_WATCHDOG)            += imx_watchdog.o
++obj-$(CONFIG_OMAP_WATCHDOG)           += omap_wdt.o
++obj-$(CONFIG_S5P)                     += s5p_wdt.o
++obj-$(CONFIG_TNETV107X_WATCHDOG)      += tnetv107x_wdt.o
++obj-$(CONFIG_XILINX_TB_WATCHDOG)      += xilinx_tb_wdt.o
index d5993b4d26d6ba6018031cc5b31f7966d13a5ca8,ee53a582515f15ac43e29dfa92703ed66ca24652..3f6e5593ed0619aaa0dba7f812d8f7e85ac0ccdb
@@@ -19,7 -19,6 +19,7 @@@ struct watchdog_regs 
  #define WCR_WDBG      0x02
  #define WCR_WDE               0x04    /* WDOG enable */
  #define WCR_WDT               0x08
 +#define WCR_SRS               0x10
  #define WCR_WDW               0x80
  #define SET_WCR_WT(x) (x << 8)
  
@@@ -46,7 -45,7 +46,7 @@@ void hw_watchdog_init(void
  #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
  #endif
        timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
 -      writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT |
 +      writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
                WCR_WDW | SET_WCR_WT(timeout), &wdog->wcr);
        hw_watchdog_reset();
  }
@@@ -56,12 -55,7 +56,7 @@@ void reset_cpu(ulong addr
  {
        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
  
-       writew(WCR_WDE, &wdog->wcr);
-       writew(0x5555, &wdog->wsr);
-       writew(0xaaaa, &wdog->wsr);     /* load minimum 1/2 second timeout */
        while (1) {
-               /*
-                * spin for .5 seconds before reset
-                */
+               writew(0, &wdog->wcr); /* clear SRS initiating SOFT reset */
        }
  }
diff --combined dts/Kconfig
index 5fe63f8025879a7fca596cd403a409f601ca97e8,0000000000000000000000000000000000000000..3a180d5b6fa39526390c15425825762e8adc8e49
mode 100644,000000..100644
--- /dev/null
@@@ -1,55 -1,0 +1,59 @@@
 +#
 +# Device Tree Control
 +#
 +# TODO:
 +#   This feature is not currently supported for SPL,
 +#    but this restriction should be removed in the future.
 +
 +config SUPPORT_OF_CONTROL
 +      bool
 +
 +menu "Device Tree Control"
 +      depends on !SPL_BUILD
 +      depends on SUPPORT_OF_CONTROL
 +
 +config OF_CONTROL
 +      bool "Run-time configuration via Device Tree"
 +      help
 +        This feature provides for run-time configuration of U-Boot
 +        via a flattened device tree.
 +
 +choice
 +      prompt "Provider of DTB for DT control"
 +      depends on OF_CONTROL
 +
 +config OF_SEPARATE
 +      bool "Separate DTB for DT control"
 +      depends on !SANDBOX
 +      help
 +        If this option is enabled, the device tree will be built and
 +        placed as a separate u-boot.dtb file alongside the U-Boot image.
 +
 +config OF_EMBED
 +      bool "Embedded DTB for DT control"
 +      help
 +        If this option is enabled, the device tree will be picked up and
 +        built into the U-Boot image.
 +
 +config OF_HOSTFILE
 +      bool "Host filed DTB for DT control"
 +      depends on SANDBOX
 +      help
 +        If this option is enabled, DTB will be read from a file on startup.
 +        This is only useful for Sandbox.  Use the -d flag to U-Boot to
 +        specify the file to read.
 +
 +endchoice
 +
 +config DEFAULT_DEVICE_TREE
 +      string "Default Device Tree for DT control"
 +      help
 +        This option specifies the default Device Tree used for DT control.
 +        It can be overridden from the command line:
 +        $ make DEVICE_TREE=<device-tree-name>
 +
++config FDT_FIXUP_PARTITIONS
++      bool
++      depends on MTD_PARTITIONS && OF_LIBFDT
++
 +endmenu
diff --combined include/ahci.h
index e8dee5357514c1cb33140da968626d8217f145ba,1940eea630e94769914964e5ba652c7d5c2669c4..2cfd6cfbd7496263e4585cc3946868ab0d5b038b
@@@ -1,4 -1,7 +1,7 @@@
  /*
+  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
+  * Terry Lv <r65388@freescale.com>
+  *
   * Copyright (C) Freescale Semiconductor, Inc. 2006.
   * Author: Jason Jin<Jason.jin@freescale.com>
   *         Zhang Wei<wei.zhang@freescale.com>
  
  #define AHCI_PCI_BAR          0x24
  #define AHCI_MAX_SG           56 /* hardware max is 64K */
+ #define AHCI_MAX_CMD_SLOT     32
  #define AHCI_CMD_SLOT_SZ      32
  #define AHCI_MAX_CMD_SLOT     32
  #define AHCI_RX_FIS_SZ                256
  #define AHCI_CMD_TBL_HDR      0x80
  #define AHCI_CMD_TBL_CDB      0x40
- #define AHCI_CMD_TBL_SZ               AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
+ #define AHCI_CMD_TBL_SZ               (AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16))
  #define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \
                                AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ)
  #define AHCI_CMD_ATAPI                (1 << 5)
  #define PORT_SCR_ERR          0x30 /* SATA phy register: SError */
  #define PORT_SCR_ACT          0x34 /* SATA phy register: SActive */
  
 +#ifdef CONFIG_SUNXI_AHCI
 +#define PORT_P0DMACR          0x70 /* SUNXI specific "DMA register" */
 +#endif
 +
  /* PORT_IRQ_{STAT,MASK} bits */
  #define PORT_IRQ_COLD_PRES    (1 << 31) /* cold presence detect */
  #define PORT_IRQ_TF_ERR               (1 << 30) /* task file error */
                                | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS \
                                | PORT_IRQ_D2H_REG_FIS
  
 +/* PORT_SCR_STAT bits */
 +#define PORT_SCR_STAT_DET_MASK        0x3
 +#define PORT_SCR_STAT_DET_COMINIT 0x1
 +#define PORT_SCR_STAT_DET_PHYRDY 0x3
 +
  /* PORT_CMD bits */
  #define PORT_CMD_ATAPI                (1 << 24) /* Device is ATAPI */
  #define PORT_CMD_LIST_ON      (1 << 15) /* cmd list DMA engine running */
  
  #define AHCI_MAX_PORTS                32
  
 -/* SETFEATURES stuff */
 -#define SETFEATURES_XFER      0x03
 -#define XFER_UDMA_7           0x47
 -#define XFER_UDMA_6           0x46
 -#define XFER_UDMA_5           0x45
 -#define XFER_UDMA_4           0x44
 -#define XFER_UDMA_3           0x43
 -#define XFER_UDMA_2           0x42
 -#define XFER_UDMA_1           0x41
 -#define XFER_UDMA_0           0x40
 -#define XFER_MW_DMA_2         0x22
 -#define XFER_MW_DMA_1         0x21
 -#define XFER_MW_DMA_0         0x20
 -#define XFER_SW_DMA_2         0x12
 -#define XFER_SW_DMA_1         0x11
 -#define XFER_SW_DMA_0         0x10
 -#define XFER_PIO_4            0x0C
 -#define XFER_PIO_3            0x0B
 -#define XFER_PIO_2            0x0A
 -#define XFER_PIO_1            0x09
 -#define XFER_PIO_0            0x08
 -#define XFER_PIO_SLOW         0x00
 -
  #define ATA_FLAG_SATA         (1 << 3)
  #define ATA_FLAG_NO_LEGACY    (1 << 4) /* no legacy mode check */
  #define ATA_FLAG_MMIO         (1 << 6) /* use MMIO, not PIO */
@@@ -152,7 -170,7 +156,7 @@@ struct ahci_probe_ent 
        u32     host_flags;
        u32     host_set_flags;
        u32     mmio_base;
-       u32     pio_mask;
+       u32     pio_mask;
        u32     udma_mask;
        u32     flags;
        u32     cap;    /* cache of HOST_CAP register */
  };
  
  int ahci_init(u32 base);
 +int ahci_reset(u32 base);
  
  #endif
index 36a36c64b8a6a19879e5236eb85af2fd5960a43d,0106d0af65f58868c94fb983add4d819189feee8..0d87e508c0d9bc66f9a324e9e781df755084ca52
   * an error value of -1.
   */
  
 -      GPIOF_INPUT,
 -      GPIOF_OUTPUT_INIT_LOW,
 -      GPIOF_OUTPUT_INIT_HIGH,
+ enum gpio_flags {
++      GPIOFLAG_INPUT,
++      GPIOFLAG_OUTPUT_INIT_LOW,
++      GPIOFLAG_OUTPUT_INIT_HIGH,
+ };
+ struct gpio {
+       unsigned int gpio;
+       enum gpio_flags flags;
+       const char *label;
+ };
  /**
 - * 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
   */
  int gpio_request(unsigned gpio, const char *label);
  
++/**
++ * Request a GPIO and configure it
++ * @param gpios       pointer to array of gpio defs
++ * @param count       number of GPIOs to set up
++ */
++int gpio_request_one(unsigned gpio, enum gpio_flags flags, const char *label);
++
++/**
++ * Request a set of GPIOs and configure them
++ * @param gpios       pointer to array of gpio defs
++ * @param count       number of GPIOs to set up
++ */
++int gpio_request_array(const struct gpio *gpios, int count);
++
  /**
   * Stop using the GPIO.  This function should not alter pin configuration.
   *
   */
  int gpio_free(unsigned gpio);
  
++/**
++ * Release a set of GPIOs
++ * @param gpios       pointer to array of gpio defs
++ * @param count       number of GPIOs to set up
++ */
++int gpio_free_array(const struct gpio *gpios, int count);
++
  /**
   * Make a GPIO an input.
   *
@@@ -82,190 -91,25 +115,190 @@@ int gpio_get_value(unsigned gpio)
   */
  int gpio_set_value(unsigned gpio, int value);
  
 +/* State of a GPIO, as reported by get_function() */
 +enum gpio_func_t {
 +      GPIOF_INPUT = 0,
 +      GPIOF_OUTPUT,
 +      GPIOF_UNUSED,           /* Not claimed */
 +      GPIOF_UNKNOWN,          /* Not known */
 +      GPIOF_FUNC,             /* Not used as a GPIO */
 +
 +      GPIOF_COUNT,
 +};
 +
 +struct udevice;
 +
  /**
 - * Request a GPIO and configure it
 - * @param gpios       pointer to array of gpio defs
 - * @param count       number of GPIOs to set up
 + * 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_request_one(unsigned gpio, enum gpio_flags flags, const char *label);
 +int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
  
  /**
 - * Request a set of GPIOs and configure them
 - * @param gpios       pointer to array of gpio defs
 - * @param count       number of GPIOs to set up
 + * 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_request_array(const struct gpio *gpios, int count);
 +int gpio_get_function(struct udevice *dev, int offset, const char **namep);
  
  /**
 - * Release a set of GPIOs
 - * @param gpios       pointer to array of gpio defs
 - * @param count       number of GPIOs to set up
 + * 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_free_array(const struct gpio *gpios, int count);
 +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
 + *
 + * Refer to functions above for description. These function largely copy
 + * the old API.
 + *
 + * This is trying to be close to Linux GPIO API. Once the U-Boot uses the
 + * new DM GPIO API, this should be really easy to flip over to the Linux
 + * GPIO API-alike interface.
 + *
 + * 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
 + * not be called.
 + *
 + * Note that @offset is the offset from the base GPIO of the device. So
 + * offset 0 is the device's first GPIO and offset o-1 is the last GPIO,
 + * where o is the number of GPIO lines controlled by the device. A device
 + * is typically used to control a single bank of GPIOs. Within complex
 + * 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 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.
 + */
 +struct dm_gpio_ops {
 +      int (*request)(struct udevice *dev, unsigned offset, const char *label);
 +      int (*free)(struct udevice *dev, unsigned offset);
 +      int (*direction_input)(struct udevice *dev, unsigned offset);
 +      int (*direction_output)(struct udevice *dev, unsigned offset,
 +                              int value);
 +      int (*get_value)(struct udevice *dev, unsigned offset);
 +      int (*set_value)(struct udevice *dev, unsigned offset, int value);
 +      /**
 +       * get_function() Get the GPIO function
 +       *
 +       * @dev:     Device to check
 +       * @offset:  GPIO offset within that device
 +       * @return current function - GPIOF_...
 +       */
 +      int (*get_function)(struct udevice *dev, unsigned offset);
 +};
 +
 +/**
 + * 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 about each
 + * device.
 + *
 + * To implement driver model support in your GPIO driver, add a probe
 + * handler, and set @gpio_count and @bank_name correctly in that handler.
 + * This tells the uclass the name of the GPIO bank and the number of GPIOs
 + * it contains.
 + *
 + * @bank_name: Name of the GPIO device (e.g 'a' means GPIOs will be called
 + * 'A0', 'A1', etc.
 + * @gpio_count: Number of GPIOs in this device
 + * @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 */
 +#define gpio_get_ops(dev)     ((struct dm_gpio_ops *)(dev)->driver->ops)
 +
 +/**
 + * gpio_get_bank_info - Return information about a GPIO bank/device
 + *
 + * This looks up a device and returns both its GPIO base name and the number
 + * of GPIOs it controls.
 + *
 + * @dev: Device to look up
 + * @offset_count: Returns number of GPIOs within this bank
 + * @return bank name of this device
 + */
 +const char *gpio_get_bank_info(struct udevice *dev, int *offset_count);
 +
 +/**
 + * gpio_lookup_name - Look up a GPIO name and return its details
 + *
 + * This is used to convert a named GPIO into a device, offset and GPIO
 + * number.
 + *
 + * @name: GPIO name to look up
 + * @devp: Returns pointer to device which contains this GPIO
 + * @offsetp: Returns the offset number within this device
 + * @gpiop: Returns the absolute GPIO number, numbered from 0
 + */
 +int gpio_lookup_name(const char *name, struct udevice **devp,
 +                   unsigned int *offsetp, unsigned int *gpiop);
 +
 +/**
 + * get_gpios() - Turn the values of a list of GPIOs into an integer
 + *
 + * This puts the value of the first GPIO into bit 0, the second into bit 1,
 + * etc. then returns the resulting integer.
 + *
 + * @gpio_list: List of GPIOs to collect
 + * @return resulting integer value
 + */
 +unsigned gpio_get_values_as_int(const int *gpio_list);
  
  #endif        /* _ASM_GENERIC_GPIO_H_ */
diff --combined include/configs/tx25.h
index 118f5bae7265e6e1c79d21ef8584f9a2429901c2,93dd3c58a864d5338d4e95ebcf39035094081f84..1d8b687905f20daf3890312908e85ee753a5dd1b
@@@ -2,7 -2,7 +2,7 @@@
   * (C) Copyright 2009 DENX Software Engineering
   * Author: John Rigby <jrigby@gmail.com>
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #ifndef __CONFIG_H
   */
  #define CONFIG_MX25
  #define CONFIG_MX25_CLK32             32000   /* OSC32K frequency */
 -#define CONFIG_SYS_HZ                 1000
 +#define CONFIG_SYS_TIMER_RATE         CONFIG_MX25_CLK32
 +#define CONFIG_SYS_TIMER_COUNTER      \
 +      (&((struct gpt_regs *)IMX_GPT1_BASE)->counter)
  
  #define       CONFIG_SYS_MONITOR_LEN          (256 << 10)     /* 256 kB for U-Boot */
  
 -#define CONFIG_SPL
  #define CONFIG_SPL_TARGET             "u-boot-with-spl.bin"
  #define CONFIG_SPL_LDSCRIPT           "arch/$(ARCH)/cpu/u-boot-spl.lds"
  #define CONFIG_SPL_MAX_SIZE           2048
   * Flash & Environment
   */
  /* No NOR flash present */
--#define CONFIG_SYS_NO_FLASH
  #define       CONFIG_ENV_IS_IN_NAND
  #define       CONFIG_ENV_OFFSET       CONFIG_SYS_MONITOR_LEN
  #define CONFIG_ENV_SIZE               (128 * 1024)    /* 128 kB NAND block size */
  #define CONFIG_ENV_OFFSET_REDUND      (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
  
  /* NAND */
--#define CONFIG_NAND_MXC
  #define CONFIG_MXC_NAND_REGS_BASE     (0xBB000000)
  #define CONFIG_SYS_MAX_NAND_DEVICE    1
  #define CONFIG_SYS_NAND_BASE          (0xBB000000)
  #define CONFIG_SYS_NAND_LARGEPAGE
  
  /* U-Boot general configuration */
 -#define CONFIG_SYS_PROMPT     "=> "   /* Monitor Command Prompt */
  #define CONFIG_SYS_CBSIZE     1024    /* Console I/O Buffer Size  */
  /* Print buffer sz */
  #define CONFIG_SYS_PBSIZE     (CONFIG_SYS_CBSIZE + \
  
  /* U-Boot commands */
  #include <config_cmd_default.h>
--#define CONFIG_CMD_NAND
--#define CONFIG_CMD_CACHE
  
  /*
   * Ethernet
   */
--#define CONFIG_FEC_MXC
--#define CONFIG_FEC_MXC_PHYADDR                0x1f
--#define CONFIG_MII
--#define CONFIG_CMD_NET
  #define CONFIG_BOARD_LATE_INIT
  #define CONFIG_ENV_OVERWRITE
  
diff --combined include/configs/tx28.h
index 0000000000000000000000000000000000000000,ac7f3d94e3a09d087aaa331e707a1142e57e0c5f..fe7cd1916e9e568f8540e82a7b4e1131f154b012
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,328 +1,299 @@@
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2012 <LW@KARO-electronics.de>
+  *
+  * SPDX-License-Identifier:      GPL-2.0
+  *
+  */
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
+ #define CONFIG_MX28                   /* must be defined before including regs-base.h */
 -#define LCD_BPP                               LCD_COLOR24
++#include <linux/sizes.h>
+ #include <asm/arch/regs-base.h>
+ /*
+  * Ka-Ro TX28 board - SoC configuration
+  */
+ #define CONFIG_MXS_GPIO                                       /* GPIO control */
+ #define CONFIG_SYS_HZ                 1000            /* Ticks per second */
+ #define PHYS_SDRAM_1_SIZE             CONFIG_SDRAM_SIZE
+ #ifdef CONFIG_TX28_S
+ #define TX28_MOD_SUFFIX                       "1"
+ #else
+ #define CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+ #define TX28_MOD_SUFFIX                       "0"
+ #endif
+ #define IRAM_BASE_ADDR                        0x00000000
+ #ifndef CONFIG_SPL_BUILD
+ #define CONFIG_SKIP_LOWLEVEL_INIT
+ #define CONFIG_SHOW_ACTIVITY
+ #define CONFIG_ARCH_CPU_INIT
+ #define CONFIG_ARCH_MISC_INIT         /* init vector table after relocation */
+ #define CONFIG_DISPLAY_CPUINFO
+ #define CONFIG_DISPLAY_BOARDINFO
+ #define CONFIG_BOARD_LATE_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
+ /* LCD Logo and Splash screen support */
+ #define CONFIG_LCD
+ #ifdef CONFIG_LCD
+ #define CONFIG_SPLASH_SCREEN
+ #define CONFIG_SPLASH_SCREEN_ALIGN
+ #define CONFIG_VIDEO_MXS
+ #define CONFIG_LCD_LOGO
 -#define CONFIG_SYS_NO_FLASH
++#define LCD_BPP                               LCD_COLOR32
+ #define CONFIG_CMD_BMP
+ #define CONFIG_VIDEO_BMP_RLE8
+ #endif /* CONFIG_LCD */
+ #endif /* CONFIG_SPL_BUILD */
+ /*
+  * Memory configuration options
+  */
+ #define CONFIG_NR_DRAM_BANKS          0x1             /* 1 bank of SDRAM */
+ #define PHYS_SDRAM_1                  0x40000000      /* SDRAM Bank #1 */
+ #define CONFIG_STACKSIZE              SZ_64K
+ #define CONFIG_SYS_MALLOC_LEN         SZ_4M
+ #define CONFIG_SYS_MEMTEST_START      PHYS_SDRAM_1    /* Memtest start address */
+ #define CONFIG_SYS_MEMTEST_END                (CONFIG_SYS_MEMTEST_START + SZ_4M)
+ /*
+  * U-Boot general configurations
+  */
+ #define CONFIG_SYS_LONGHELP
+ #define CONFIG_SYS_PROMPT             "TX28 U-Boot > "
+ #define CONFIG_SYS_CBSIZE             2048            /* Console I/O buffer size */
+ #define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                                       /* Print buffer size */
+ #define CONFIG_SYS_MAXARGS            256             /* Max number of command args */
+ #define CONFIG_SYS_BARGSIZE           CONFIG_SYS_CBSIZE
+                                       /* Boot argument buffer size */
+ #define CONFIG_VERSION_VARIABLE               /* U-BOOT version */
+ #define CONFIG_AUTO_COMPLETE          /* Command auto complete */
+ #define CONFIG_CMDLINE_EDITING                /* Command history etc */
+ #define CONFIG_SYS_64BIT_VSPRINTF
 -#define CONFIG_OF_LIBFDT
+ /*
+  * Flattened Device Tree (FDT) support
+ */
 -#define CONFIG_FDT_FIXUP_PARTITIONS
 -#define CONFIG_OF_BOARD_SETUP
+ #ifdef CONFIG_OF_LIBFDT
 -#define CONFIG_CMD_CACHE
 -#define CONFIG_CMD_MMC
 -#define CONFIG_CMD_NAND
 -#define CONFIG_CMD_MTDPARTS
 -#define CONFIG_CMD_BOOTCE
 -#define CONFIG_CMD_TIME
 -#define CONFIG_CMD_MEMTEST
+ #endif
+ /*
+  * Boot Linux
+  */
+ #define xstr(s)                               str(s)
+ #define str(s)                                #s
+ #define __pfx(x, s)                   (x##s)
+ #define _pfx(x, s)                    __pfx(x, s)
+ #define CONFIG_CMDLINE_TAG
+ #define CONFIG_SETUP_MEMORY_TAGS
+ #define CONFIG_BOOTDELAY              3
+ #define CONFIG_ZERO_BOOTDELAY_CHECK
+ #define CONFIG_SYS_AUTOLOAD           "no"
+ #define CONFIG_BOOTFILE                       "uImage"
+ #define CONFIG_BOOTARGS                       "init=/linuxrc console=ttyAMA0,115200 ro debug panic=1"
+ #define CONFIG_BOOTCOMMAND            "run bootcmd_${boot_mode} bootm_cmd"
+ #ifdef CONFIG_TX28_S
+ #define CONFIG_LOADADDR                       41000000
+ #else
+ #define CONFIG_LOADADDR                       43000000
+ #endif
+ #define CONFIG_FDTADDR                        41000000
+ #define CONFIG_SYS_LOAD_ADDR          _pfx(0x, CONFIG_LOADADDR)
+ #define CONFIG_SYS_FDT_ADDR           _pfx(0x, CONFIG_FDTADDR)
+ #define CONFIG_U_BOOT_IMG_SIZE                SZ_1M
+ /*
+  * Extra Environment Settings
+  */
+ #ifdef CONFIG_ENV_IS_NOWHERE
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "autoload=no\0"                                                 \
+       "bootdelay=-1\0"                                                \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"
+ #else
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p3 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs;nboot linux\0"\
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+ #endif /*  CONFIG_ENV_IS_NOWHERE */
+ #define MTD_NAME                      "gpmi-nand"
+ #define MTDIDS_DEFAULT                        "nand0=" MTD_NAME
+ /*
+  * U-Boot Commands
+  */
+ #include <config_cmd_default.h>
 -#define CONFIG_FEC_MXC
+ /*
+  * Serial Driver
+  */
+ #define CONFIG_PL011_SERIAL
+ #define CONFIG_PL011_CLOCK            24000000
+ #define CONFIG_PL01x_PORTS    {       \
+       (void *)MXS_UARTDBG_BASE,       \
+       }
+ #define CONFIG_CONS_INDEX             0               /* do not change! */
+ #define CONFIG_BAUDRATE                       115200          /* Default baud rate */
+ #define CONFIG_SYS_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, }
+ #define CONFIG_SYS_CONSOLE_INFO_QUIET
+ /*
+  * Ethernet Driver
+  */
 -#define CONFIG_FEC_MXC_MULTI
+ #ifdef CONFIG_FEC_MXC
+ /* This is required for the FEC driver to work with cache enabled */
+ #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+ #define CONFIG_SYS_CACHELINE_SIZE     32
+ #ifndef CONFIG_TX28_S
 -#define CONFIG_FEC_MXC_PHYADDR                0x00
+ #else
+ #define IMX_FEC_BASE                  MXS_ENET0_BASE
 -#define CONFIG_PHY_SMSC
 -#define CONFIG_PHYLIB
 -#define CONFIG_MII
+ #endif
 -#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+ #define CONFIG_FEC_XCV_TYPE           RMII
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_PING
+ #define CONFIG_NET_MULTI
+ #define CONFIG_CMD_MII
 -#define CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_ENV_IS_IN_MMC
+ /* Add for working with "strict" DHCP server */
+ #define CONFIG_BOOTP_SUBNETMASK
+ #define CONFIG_BOOTP_GATEWAY
+ #define CONFIG_BOOTP_DNS
+ #define CONFIG_BOOTP_RANDOM_ID
+ #endif
+ #ifndef CONFIG_ENV_IS_NOWHERE
+ /* define one of the following options:
 -#define CONFIG_ENV_IS_IN_NAND
+ */
 -#define CONFIG_MTD_DEVICE
+ #endif
+ #define CONFIG_ENV_OVERWRITE
+ /*
+  * NAND flash driver
+  */
+ #ifdef CONFIG_CMD_NAND
+ #define CONFIG_SYS_NAND_BLOCK_SIZE    SZ_128K
 -#define CONFIG_CMD_NAND_TRIMFFS
+ #define CONFIG_NAND_MXS
+ #define CONFIG_APBH_DMA
+ #define CONFIG_APBH_DMA_BURST
+ #define CONFIG_APBH_DMA_BURST8
+ #define CONFIG_SYS_NAND_U_BOOT_OFFS   CONFIG_SYS_NAND_BLOCK_SIZE
 -#define CONFIG_SYS_NAND_USE_FLASH_BBT
+ #define CONFIG_SYS_MXS_DMA_CHANNEL    4
+ #define CONFIG_SYS_NAND_MAX_CHIPS     0x1
+ #define CONFIG_SYS_MAX_NAND_DEVICE    0x1
+ #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 -#define CONFIG_CMD_ROMUPDATE
+ #define CONFIG_SYS_NAND_BASE          0x00000000
 -#define CONFIG_MMC
 -#define CONFIG_GENERIC_MMC
+ #else
+ #undef CONFIG_ENV_IS_IN_NAND
+ #endif /* CONFIG_CMD_NAND */
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_OFFSET             (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+ #define CONFIG_ENV_SIZE                       SZ_128K
+ #define CONFIG_ENV_RANGE              (3 * CONFIG_SYS_NAND_BLOCK_SIZE)
+ #endif /* CONFIG_ENV_IS_IN_NAND */
+ #ifdef CONFIG_ENV_OFFSET_REDUND
+ #define CONFIG_SYS_ENV_PART_STR               xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"                                                        \
+       xstr(CONFIG_SYS_ENV_PART_SIZE)                                  \
+       "(env2),"
+ #define CONFIG_SYS_USERFS_PART_STR    xstr(CONFIG_SYS_USERFS_PART_SIZE2) "(userfs)"
+ #else
+ #define CONFIG_SYS_ENV_PART_STR               xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"
+ #define CONFIG_SYS_USERFS_PART_STR    xstr(CONFIG_SYS_USERFS_PART_SIZE) "(userfs)"
+ #endif /* CONFIG_ENV_OFFSET_REDUND */
+ /*
+  * MMC Driver
+  */
+ #ifdef CONFIG_CMD_MMC
+ #define CONFIG_MXS_MMC
+ #define CONFIG_BOUNCE_BUFFER
+ #define CONFIG_DOS_PARTITION
+ #define CONFIG_CMD_FAT
+ #define CONFIG_FAT_WRITE
+ #define CONFIG_CMD_EXT2
+ /*
+  * Environments on MMC
+  */
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ /* Associated with the MMC layout defined in mmcops.c */
+ #define CONFIG_ENV_OFFSET             SZ_1K
+ #define CONFIG_ENV_SIZE                       (SZ_128K - CONFIG_ENV_OFFSET)
+ #define CONFIG_DYNAMIC_MMC_DEVNO
+ #endif /* CONFIG_ENV_IS_IN_MMC */
+ #else
+ #undef CONFIG_ENV_IS_IN_MMC
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_ENV_IS_NOWHERE
+ #undef CONFIG_ENV_SIZE
+ #define CONFIG_ENV_SIZE                       SZ_4K
+ #endif
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "1m@" xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) "(u-boot),"             \
+       CONFIG_SYS_ENV_PART_STR                                         \
+       "6m(linux),32m(rootfs)," CONFIG_SYS_USERFS_PART_STR             \
+       ",512k@" xstr(CONFIG_SYS_NAND_DTB_OFFSET) "(dtb)"               \
+       ",512k@" xstr(CONFIG_SYS_NAND_BBT_OFFSET) "(bbt)ro"
+ #define CONFIG_SYS_SDRAM_BASE         PHYS_SDRAM_1
+ #define CONFIG_SYS_INIT_SP_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+ /* Defines for SPL */
+ #define CONFIG_SPL
+ #define CONFIG_SPL_START_S_PATH               "arch/arm/cpu/arm926ejs/mxs"
+ #define CONFIG_SPL_LDSCRIPT           "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
+ #define CONFIG_SPL_LIBCOMMON_SUPPORT
+ #define CONFIG_SPL_LIBGENERIC_SUPPORT
+ #define CONFIG_SPL_SERIAL_SUPPORT
+ #define CONFIG_SPL_GPIO_SUPPORT
+ #define CONFIG_SYS_SPL_VDDD_VAL               1500
+ #define CONFIG_SYS_SPL_BATT_BO_LEVEL  2800
+ #define CONFIG_SYS_SPL_VDDMEM_VAL     0       /* VDDMEM is not utilized on TX28 */
+ #endif /* __CONFIGS_TX28_H */
diff --combined include/configs/tx48.h
index 0000000000000000000000000000000000000000,dd7cf74a23d909c488a35a06d784a757c4c4564e..9c21e1022223158f5a966c4f66fd492d228c805d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,348 +1,324 @@@
 -#include <asm/sizes.h>
+ /*
+  * tx48.h
+  *
+  * Copyright (C) 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+  *
+  * based on: am335x_evm
+  * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+  *
+  * SPDX-License-Identifier:      GPL-2.0
+  *
+  */
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
+ #define CONFIG_AM33XX                 /* must be set before including omap.h */
 -#define CONFIG_VIDEO_DA8XX
++#include <linux/sizes.h>
+ #include <asm/arch/omap.h>
+ /*
+  * Ka-Ro TX48 board - SoC configuration
+  */
+ #define CONFIG_OMAP
+ #define CONFIG_AM33XX_GPIO
+ #define CONFIG_SYS_HZ                 1000    /* Ticks per second */
+ #ifndef CONFIG_SPL_BUILD
+ #define CONFIG_SKIP_LOWLEVEL_INIT
+ #define CONFIG_SHOW_ACTIVITY
+ #define CONFIG_DISPLAY_CPUINFO
+ #define CONFIG_DISPLAY_BOARDINFO
+ #define CONFIG_BOARD_LATE_INIT
+ /* LCD Logo and Splash screen support */
+ #define CONFIG_LCD
+ #ifdef CONFIG_LCD
+ #define CONFIG_SPLASH_SCREEN
+ #define CONFIG_SPLASH_SCREEN_ALIGN
 -#define LCD_BPP                               LCD_COLOR24
++#define CONFIG_AM335X_LCD
+ #define DAVINCI_LCD_CNTL_BASE         0x4830e000
+ #define CONFIG_LCD_LOGO
 -#define CONFIG_SYS_NO_FLASH
++#define LCD_BPP                               LCD_COLOR32
+ #define CONFIG_CMD_BMP
+ #define CONFIG_VIDEO_BMP_RLE8
+ #endif /* CONFIG_LCD */
+ #endif /* CONFIG_SPL_BUILD */
+ /* Clock Defines */
+ #define V_OSCK                                24000000  /* Clock output from T2 */
+ #define V_SCLK                                V_OSCK
+ /*
+  * Memory configuration options
+  */
+ #define CONFIG_SYS_SDRAM_DDR3
+ #define CONFIG_NR_DRAM_BANKS          0x1             /* '1' would be converted to 'y' by define2mk.sed */
+ #define PHYS_SDRAM_1                  0x80000000      /* SDRAM Bank #1 */
+ #define CONFIG_MAX_RAM_BANK_SIZE      SZ_1G
+ #define CONFIG_STACKSIZE              SZ_64K
+ #define CONFIG_SYS_MALLOC_LEN         SZ_4M
+ #define CONFIG_SYS_MEMTEST_START      (PHYS_SDRAM_1 + SZ_64M)
+ #define CONFIG_SYS_MEMTEST_END                (CONFIG_SYS_MEMTEST_START + SZ_8M)
+ #define CONFIG_SYS_CACHELINE_SIZE     64
+ /*
+  * U-Boot general configurations
+  */
+ #define CONFIG_SYS_LONGHELP
+ #define CONFIG_SYS_PROMPT             "TX48 U-Boot > "
+ #define CONFIG_SYS_CBSIZE             2048    /* Console I/O buffer size */
+ #define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+ #define CONFIG_SYS_MAXARGS            256     /* Max number of command args */
+ #define CONFIG_SYS_BARGSIZE           CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+ #define CONFIG_VERSION_VARIABLE                       /* U-BOOT version */
+ #define CONFIG_AUTO_COMPLETE                  /* Command auto complete */
+ #define CONFIG_CMDLINE_EDITING                        /* Command history etc */
+ #define CONFIG_SYS_64BIT_VSPRINTF
 -#define CONFIG_OF_LIBFDT
 -#define CONFIG_OF_BOARD_SETUP
+ /*
+  * Flattened Device Tree (FDT) support
+ */
 -#define CONFIG_HW_WATCHDOG
+ /*
+  * Boot Linux
+  */
+ #define xstr(s)                               str(s)
+ #define str(s)                                #s
+ #define __pfx(x, s)                   (x##s)
+ #define _pfx(x, s)                    __pfx(x, s)
+ #define CONFIG_CMDLINE_TAG
+ #define CONFIG_SETUP_MEMORY_TAGS
+ #define CONFIG_BOOTDELAY              3
+ #define CONFIG_ZERO_BOOTDELAY_CHECK
+ #define CONFIG_SYS_AUTOLOAD           "no"
+ #define CONFIG_BOOTFILE                       "uImage"
+ #define CONFIG_BOOTARGS                       "init=/linuxrc console=ttyO0,115200 ro debug panic=1"
+ #define CONFIG_BOOTCOMMAND            "run bootcmd_${boot_mode} bootm_cmd"
+ #define CONFIG_LOADADDR                       83000000
+ #define CONFIG_FDTADDR                        81000000
+ #define CONFIG_SYS_LOAD_ADDR          _pfx(0x, CONFIG_LOADADDR)
+ #define CONFIG_SYS_FDT_ADDR           _pfx(0x, CONFIG_FDTADDR)
+ #define CONFIG_U_BOOT_IMG_SIZE                SZ_1M
 -#define CONFIG_FDT_FIXUP_PARTITIONS
+ /*
+  * Extra Environment Settings
+  */
+ #define CONFIG_SYS_CPU_CLK_STR                xstr(CONFIG_SYS_MPU_CLK)
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock4 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=" CONFIG_SYS_CPU_CLK_STR "\0"                          \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+ #define MTD_NAME                      "omap2-nand.0"
+ #define MTDIDS_DEFAULT                        "nand0=" MTD_NAME
 -#define CONFIG_CMD_CACHE
 -#define CONFIG_CMD_MMC
 -#define CONFIG_CMD_NAND
 -#define CONFIG_CMD_MTDPARTS
 -#define CONFIG_CMD_BOOTCE
 -#define CONFIG_CMD_TIME
 -#define CONFIG_CMD_MEMTEST
+ /*
+  * U-Boot Commands
+  */
+ #include <config_cmd_default.h>
 -#define CONFIG_PHY_SMSC
 -#define CONFIG_PHYLIB
 -#define CONFIG_MII
+ /*
+  * Serial Driver
+  */
+ #define CONFIG_SYS_NS16550
+ #define CONFIG_SYS_NS16550_SERIAL
+ #define CONFIG_SYS_NS16550_MEM32
+ #define CONFIG_SYS_NS16550_REG_SIZE   (-4)
+ #define CONFIG_SYS_NS16550_CLK                48000000
+ #define CONFIG_SYS_NS16550_COM1               0x44e09000      /* UART0 */
+ #define CONFIG_SYS_NS16550_COM2               0x48022000      /* UART1 */
+ #define CONFIG_SYS_NS16550_COM6               0x481aa000      /* UART5 */
+ #define CONFIG_SYS_NS16550_COM3               0x481aa000      /* UART2 */
+ #define CONFIG_SYS_NS16550_COM4               0x481aa000      /* UART3 */
+ #define CONFIG_SYS_NS16550_COM5               0x481aa000      /* UART4 */
+ #define CONFIG_CONS_INDEX             1               /* one based! */
+ #define CONFIG_BAUDRATE                       115200          /* Default baud rate */
+ #define CONFIG_SYS_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, }
+ #define CONFIG_SYS_CONSOLE_INFO_QUIET
+ /*
+  * Ethernet Driver
+  */
+ #ifdef CONFIG_CMD_NET
+ #define CONFIG_DRIVER_TI_CPSW
+ #define CONFIG_NET_MULTI
+ #define CONFIG_PHY_GIGE
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_PING
+ #define CONFIG_CMD_MII
 -#define CONFIG_MTD_DEVICE
 -#define CONFIG_ENV_IS_IN_NAND
+ /* Add for working with "strict" DHCP server */
+ #define CONFIG_BOOTP_SUBNETMASK
+ #define CONFIG_BOOTP_GATEWAY
+ #define CONFIG_BOOTP_DNS
+ #define CONFIG_BOOTP_DNS2
+ #endif
+ /*
+  * NAND flash driver
+  */
+ #ifdef CONFIG_CMD_NAND
 -#define CONFIG_CMD_NAND_TRIMFFS
+ #define CONFIG_NAND_OMAP_GPMC
+ #ifndef CONFIG_SPL_BUILD
+ #define CONFIG_SYS_GPMC_PREFETCH_ENABLE
+ #endif
+ #define GPMC_NAND_ECC_LP_x8_LAYOUT
+ #define GPMC_NAND_HW_ECC_LAYOUT_KERNEL        GPMC_NAND_HW_ECC_LAYOUT
+ #define CONFIG_SYS_NAND_U_BOOT_OFFS   0x20000
+ #define CONFIG_SYS_NAND_PAGE_SIZE     2048
+ #define CONFIG_SYS_NAND_OOBSIZE               64
+ #define CONFIG_SYS_NAND_ECCSIZE               512
+ #define CONFIG_SYS_NAND_ECCBYTES      14
 -#define CONFIG_SYS_NAND_USE_FLASH_BBT
+ #define CONFIG_SYS_NAND_MAX_CHIPS     0x1
+ #define CONFIG_SYS_NAND_MAXBAD                20 /* Max. number of bad blocks guaranteed by manufacturer */
+ #define CONFIG_SYS_MAX_NAND_DEVICE    0x1
+ #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 -#define CONFIG_ENV_IS_IN_MMC
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_OVERWRITE
+ #define CONFIG_ENV_OFFSET             (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+ #define CONFIG_ENV_SIZE                       SZ_128K
+ #define CONFIG_ENV_RANGE              0x60000
+ #endif /* CONFIG_ENV_IS_IN_NAND */
+ #define CONFIG_SYS_NAND_BASE          0x00100000
+ #define CONFIG_SYS_NAND_SIZE          SZ_128M
+ #define NAND_BASE                     CONFIG_SYS_NAND_BASE
+ #endif /* CONFIG_CMD_NAND */
+ /*
+  * MMC Driver
+  */
+ #ifdef CONFIG_CMD_MMC
+ #ifndef CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_MMC
 -#define CONFIG_GENERIC_MMC
+ #endif
+ #define CONFIG_OMAP_HSMMC
+ #define CONFIG_OMAP_MMC_DEV_1
+ #define CONFIG_DOS_PARTITION
+ #define CONFIG_CMD_FAT
+ #define CONFIG_FAT_WRITE
+ #define CONFIG_CMD_EXT2
+ /*
+  * Environments on MMC
+  */
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ #define CONFIG_ENV_OVERWRITE
+ /* Associated with the MMC layout defined in mmcops.c */
+ #define CONFIG_ENV_OFFSET             SZ_1K
+ #define CONFIG_ENV_SIZE                       (SZ_128K - CONFIG_ENV_OFFSET)
+ #define CONFIG_DYNAMIC_MMC_DEVNO
+ #endif /* CONFIG_ENV_IS_IN_MMC */
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_ENV_OFFSET_REDUND
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "128k(u-boot-spl),"                                             \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89216k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #else
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "128k(u-boot-spl),"                                             \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89600k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #endif
+ #define CONFIG_SYS_SDRAM_BASE         PHYS_SDRAM_1
+ #define SRAM0_SIZE                    SZ_64K
+ #define OCMC_SRAM_BASE                        0x40300000
+ #define CONFIG_SPL_STACK              (OCMC_SRAM_BASE + 0xb800)
+ #define CONFIG_SYS_INIT_SP_ADDR               (PHYS_SDRAM_1 + SZ_32K)
+  /* Platform/Board specific defs */
+ #define CONFIG_SYS_TIMERBASE          0x48040000      /* Use Timer2 */
+ #define CONFIG_SYS_PTV                        2       /* Divisor: 2^(PTV+1) => 8 */
+ /* Defines for SPL */
+ #define CONFIG_SPL
+ #define CONFIG_SPL_FRAMEWORK
+ #define CONFIG_SPL_MAX_SIZE           (SRAM_SCRATCH_SPACE_ADDR - CONFIG_SPL_TEXT_BASE)
+ #define CONFIG_SPL_GPIO_SUPPORT
+ #ifdef CONFIG_NAND_OMAP_GPMC
+ #define CONFIG_SPL_NAND_SUPPORT
+ #define CONFIG_SPL_NAND_DRIVERS
+ #define CONFIG_SPL_NAND_BASE
+ #define CONFIG_SPL_NAND_ECC
+ #define CONFIG_SPL_NAND_AM33XX_BCH
+ #define CONFIG_SYS_NAND_5_ADDR_CYCLE
+ #define CONFIG_SYS_NAND_PAGE_COUNT    (CONFIG_SYS_NAND_BLOCK_SIZE /   \
+                                       CONFIG_SYS_NAND_PAGE_SIZE)
+ #define CONFIG_SYS_NAND_BLOCK_SIZE    SZ_128K
+ #define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS
+ #define CONFIG_SYS_NAND_ECCPOS                { 2, 3, 4, 5, 6, 7, 8, 9, \
+                                        10, 11, 12, 13, 14, 15, 16, 17, \
+                                        18, 19, 20, 21, 22, 23, 24, 25, \
+                                        26, 27, 28, 29, 30, 31, 32, 33, \
+                                        34, 35, 36, 37, 38, 39, 40, 41, \
+                                        42, 43, 44, 45, 46, 47, 48, 49, \
+                                        50, 51, 52, 53, 54, 55, 56, 57, }
+ #endif
+ #define CONFIG_SPL_BSS_START_ADDR     PHYS_SDRAM_1
+ #define CONFIG_SPL_BSS_MAX_SIZE               SZ_512K
+ #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR       0x300 /* address 0x60000 */
+ #define CONFIG_SPL_LIBCOMMON_SUPPORT
+ #define CONFIG_SPL_LIBGENERIC_SUPPORT
+ #define CONFIG_SPL_SERIAL_SUPPORT
+ #define CONFIG_SPL_YMODEM_SUPPORT
+ #define CONFIG_SPL_LDSCRIPT           "$(CPUDIR)/omap-common/u-boot-spl.lds"
+ /*
+  * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
+  * 64 bytes before this address should be set aside for u-boot.img's
+  * header. That is 0x800FFFC0--0x80100000 should not be used for any
+  * other needs.
+  */
+ #define CONFIG_SYS_SPL_MALLOC_START   (PHYS_SDRAM_1 + SZ_2M + SZ_32K)
+ #define CONFIG_SYS_SPL_MALLOC_SIZE    SZ_1M
+ #endif        /* __CONFIG_H */
diff --combined include/configs/tx51.h
index 0000000000000000000000000000000000000000,19bb7c49865b84d9ffe19697e451c8aaa37824b0..74a9076bab72cb3144c10efbf10c094a7896bcb4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,279 +1,249 @@@
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
+  *
+  * SPDX-License-Identifier:      GPL-2.0
+  *
+  */
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
+ #define CONFIG_MX51                   /* must be set before including imx-regs.h */
 -#define LCD_BPP                               LCD_COLOR24
++#include <linux/sizes.h>
+ #include <asm/arch/imx-regs.h>
+ /*
+  * Ka-Ro TX51 board - SoC configuration
+  */
+ #define CONFIG_SYS_MX5_IOMUX_V3
+ #define CONFIG_MXC_GPIO                       /* GPIO control */
+ #define CONFIG_SYS_MX5_HCLK           24000000
+ #define CONFIG_SYS_DDR_CLKSEL         0
+ #define CONFIG_SYS_HZ                 1000    /* Ticks per second */
+ #define CONFIG_SHOW_ACTIVITY
+ #define CONFIG_DISPLAY_BOARDINFO
+ #define CONFIG_BOARD_LATE_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
+ #if CONFIG_SYS_CPU_CLK == 600
+ #define TX51_MOD_PREFIX                       "6"
+ #elif CONFIG_SYS_CPU_CLK == 800
+ #define TX51_MOD_PREFIX                       "8"
+ #define CONFIG_MX51_PLL_ERRATA
+ #else
+ #error Invalid CPU clock
+ #endif
+ /* LCD Logo and Splash screen support */
+ #define CONFIG_LCD
+ #ifdef CONFIG_LCD
+ #define CONFIG_SPLASH_SCREEN
+ #define CONFIG_SPLASH_SCREEN_ALIGN
+ #define CONFIG_VIDEO_IPUV3
+ #define CONFIG_IPUV3_CLK              133000000
+ #define CONFIG_LCD_LOGO
 -#define CONFIG_SYS_NO_FLASH
++#define LCD_BPP                               LCD_COLOR32
+ #define CONFIG_CMD_BMP
+ #define CONFIG_VIDEO_BMP_RLE8
+ #endif /* CONFIG_LCD */
+ /*
+  * Memory configuration options
+  */
+ #define PHYS_SDRAM_1                  0x90000000      /* Base address of bank 1 */
+ #define PHYS_SDRAM_1_SIZE             SZ_128M
+ #if CONFIG_NR_DRAM_BANKS > 1
+ #define PHYS_SDRAM_2                  0x98000000      /* Base address of bank 2 */
+ #define PHYS_SDRAM_2_SIZE             SZ_128M
+ #endif
+ #define CONFIG_STACKSIZE              SZ_128K
+ #define CONFIG_SYS_MALLOC_LEN         SZ_8M
+ #define CONFIG_SYS_MEMTEST_START      PHYS_SDRAM_1    /* Memtest start address */
+ #define CONFIG_SYS_MEMTEST_END                (PHYS_SDRAM_1 + SZ_4M)  /* 4 MB RAM test */
+ #define CONFIG_SYS_SDRAM_CLK          166
+ #define CONFIG_SYS_CLKTL_CBCDR                0x01e35100
+ /*
+  * U-Boot general configurations
+  */
+ #define CONFIG_SYS_LONGHELP
+ #define CONFIG_SYS_PROMPT             "TX51 U-Boot > "
+ #define CONFIG_SYS_CBSIZE             2048    /* Console I/O buffer size */
+ #define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+ #define CONFIG_SYS_MAXARGS            256     /* Max number of command args */
+ #define CONFIG_SYS_BARGSIZE           CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+ #define CONFIG_VERSION_VARIABLE                       /* U-BOOT version */
+ #define CONFIG_AUTO_COMPLETE                  /* Command auto complete */
+ #define CONFIG_CMDLINE_EDITING                        /* Command history etc */
+ #define CONFIG_SYS_64BIT_VSPRINTF
 -#define CONFIG_OF_LIBFDT
 -#define CONFIG_OF_BOARD_SETUP
+ /*
+  * Flattened Device Tree (FDT) support
+ */
 -#define CONFIG_HW_WATCHDOG
+ /*
+  * Boot Linux
+  */
+ #define xstr(s)                               str(s)
+ #define str(s)                                #s
+ #define __pfx(x, s)                   (x##s)
+ #define _pfx(x, s)                    __pfx(x, s)
+ #define CONFIG_CMDLINE_TAG
+ #define CONFIG_SETUP_MEMORY_TAGS
+ #define CONFIG_BOOTDELAY              3
+ #define CONFIG_ZERO_BOOTDELAY_CHECK
+ #define CONFIG_SYS_AUTOLOAD           "no"
+ #define CONFIG_BOOTFILE                       "uImage"
+ #define CONFIG_BOOTARGS                       "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+ #define CONFIG_BOOTCOMMAND            "run bootcmd_${boot_mode} bootm_cmd"
+ #define CONFIG_LOADADDR                       94000000
+ #define CONFIG_FDTADDR                        91000000
+ #define CONFIG_SYS_LOAD_ADDR          _pfx(0x, CONFIG_LOADADDR)
+ #define CONFIG_SYS_FDT_ADDR           _pfx(0x, CONFIG_FDTADDR)
+ #define CONFIG_U_BOOT_IMG_SIZE                SZ_1M
 -#define CONFIG_FDT_FIXUP_PARTITIONS
+ /*
+  * Extra Environment Settings
+  */
+ #define CONFIG_SYS_CPU_CLK_STR                xstr(CONFIG_SYS_CPU_CLK)
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=" CONFIG_SYS_CPU_CLK_STR "\0"                          \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+ #define MTD_NAME                      "mxc_nand"
+ #define MTDIDS_DEFAULT                        "nand0=" MTD_NAME
 -#define CONFIG_CMD_CACHE
 -#define CONFIG_CMD_MMC
 -#define CONFIG_CMD_NAND
 -#define CONFIG_CMD_MTDPARTS
 -#define CONFIG_CMD_BOOTCE
 -#define CONFIG_CMD_TIME
 -#define CONFIG_CMD_MEMTEST
+ /*
+  * U-Boot Commands
+  */
+ #include <config_cmd_default.h>
 -#define CONFIG_FEC_MXC
+ /*
+  * Serial Driver
+  */
+ #define CONFIG_MXC_UART
+ #define CONFIG_MXC_UART_BASE          UART1_BASE
+ #define CONFIG_MXC_GPIO
+ #define CONFIG_BAUDRATE                       115200          /* Default baud rate */
+ #define CONFIG_SYS_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, }
+ #define CONFIG_SYS_CONSOLE_INFO_QUIET
+ /*
+  * Ethernet Driver
+  */
 -#define CONFIG_FEC_MXC_PHYADDR                0x1f
 -#define CONFIG_PHYLIB
 -#define CONFIG_PHY_SMSC
 -#define CONFIG_MII
+ #ifdef CONFIG_FEC_MXC
+ #define IMX_FEC_BASE                  FEC_BASE_ADDR
 -#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+ #define CONFIG_FEC_XCV_TYPE           MII100
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_PING
+ #define CONFIG_CMD_MII
 -#define CONFIG_MTD_DEVICE
 -#define CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_NAND_MXC
+ /* Add for working with "strict" DHCP server */
+ #define CONFIG_BOOTP_SUBNETMASK
+ #define CONFIG_BOOTP_GATEWAY
+ #define CONFIG_BOOTP_DNS
+ #endif
+ /*
+  * NAND flash driver
+  */
+ #ifdef CONFIG_CMD_NAND
 -#define CONFIG_CMD_NAND_TRIMFFS
+ #define CONFIG_MXC_NAND_REGS_BASE     NFC_BASE_ADDR_AXI
+ #define CONFIG_MXC_NAND_IP_REGS_BASE  NFC_BASE_ADDR
+ #define CONFIG_MXC_NAND_HWECC
 -#define CONFIG_SYS_NAND_USE_FLASH_BBT
+ #define CONFIG_SYS_NAND_MAX_CHIPS     0x1
+ #define CONFIG_SYS_MAX_NAND_DEVICE    0x1
+ #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 -#define CONFIG_CMD_ROMUPDATE
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_OVERWRITE
+ #define CONFIG_ENV_OFFSET             CONFIG_U_BOOT_IMG_SIZE
+ #define CONFIG_ENV_SIZE                       0x20000 /* 128 KiB */
+ #define CONFIG_ENV_RANGE              0x60000
+ #endif
+ #define CONFIG_SYS_NAND_BASE          0x00000000
 -#define CONFIG_ENV_IS_IN_MMC
+ #endif /* CONFIG_CMD_NAND */
+ /*
+  * MMC Driver
+  */
+ #ifdef CONFIG_CMD_MMC
+ #ifndef CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_MMC
 -#define CONFIG_GENERIC_MMC
 -#define CONFIG_FSL_ESDHC
+ #endif
+ #define CONFIG_SYS_FSL_ESDHC_ADDR     0
+ #define CONFIG_DOS_PARTITION
+ #define CONFIG_CMD_FAT
+ #define CONFIG_FAT_WRITE
+ #define CONFIG_CMD_EXT2
+ /*
+  * Environments on MMC
+  */
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ #define CONFIG_ENV_OVERWRITE
+ /* Associated with the MMC layout defined in mmcops.c */
+ #define CONFIG_ENV_OFFSET             SZ_1K
+ #define CONFIG_ENV_SIZE                       (SZ_128K - CONFIG_ENV_OFFSET)
+ #define CONFIG_DYNAMIC_MMC_DEVNO
+ #endif /* CONFIG_ENV_IS_IN_MMC */
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_ENV_OFFSET_REDUND
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89344k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #else
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89728k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #endif
+ #define CONFIG_SYS_SDRAM_BASE         PHYS_SDRAM_1
+ #define CONFIG_SYS_INIT_SP_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+ #ifdef CONFIG_CMD_IIM
+ #define CONFIG_FSL_IIM
+ #endif
+ #endif /* __CONFIG_H */
diff --combined include/configs/tx53.h
index 0000000000000000000000000000000000000000,7502e6726b0323f8ccb7e9b0b705837c62d49413..3f1cd67128327cb9164f6b359dee9db6466777a6
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,294 +1,259 @@@
 -#define CONFIG_MX53                   /* must be set before including imx-regs.h */
 -
 -#include <asm/sizes.h>
+ /*
+  * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
+  *
+  * SPDX-License-Identifier:      GPL-2.0
+  *
+  */
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
 -#define CONFIG_TX53                   /* TX53 SoM */
++#include <linux/sizes.h>
+ #include <asm/arch/imx-regs.h>
+ /*
+  * Ka-Ro TX53 board - SoC configuration
+  */
 -#define LCD_BPP                               LCD_COLOR24
+ #define CONFIG_SYS_MX5_IOMUX_V3
+ #define CONFIG_MXC_GPIO                       /* GPIO control */
+ #define CONFIG_SYS_MX5_HCLK           24000000
+ #define CONFIG_SYS_DDR_CLKSEL         0
+ #define CONFIG_SYS_HZ                 1000    /* Ticks per second */
+ #define CONFIG_SHOW_ACTIVITY
+ #define CONFIG_DISPLAY_BOARDINFO
+ #define CONFIG_BOARD_LATE_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
+ /* LCD Logo and Splash screen support */
+ #define CONFIG_LCD
+ #ifdef CONFIG_LCD
+ #define CONFIG_SPLASH_SCREEN
+ #define CONFIG_SPLASH_SCREEN_ALIGN
+ #define CONFIG_VIDEO_IPUV3
+ #define CONFIG_IPUV3_CLK              200000000
+ #define CONFIG_LCD_LOGO
 -#define CONFIG_SYS_NO_FLASH
++#define LCD_BPP                               LCD_COLOR32
+ #define CONFIG_CMD_BMP
+ #define CONFIG_VIDEO_BMP_RLE8
+ #endif /* CONFIG_LCD */
+ /*
+  * Memory configuration options
+  */
+ #ifndef CONFIG_SYS_SDRAM_SIZE
+ #define CONFIG_SYS_SDRAM_SIZE         (SZ_512M * CONFIG_NR_DRAM_BANKS)
+ #endif
+ #define PHYS_SDRAM_1                  0x70000000      /* Base address of bank 1 */
+ #define PHYS_SDRAM_1_SIZE             (CONFIG_SYS_SDRAM_SIZE / CONFIG_NR_DRAM_BANKS)
+ #if CONFIG_NR_DRAM_BANKS > 1
+ #define PHYS_SDRAM_2                  0xb0000000      /* Base address of bank 2 */
+ #define PHYS_SDRAM_2_SIZE             PHYS_SDRAM_1_SIZE
+ #endif
+ #define CONFIG_STACKSIZE              SZ_128K
+ #define CONFIG_SYS_MALLOC_LEN         SZ_8M
+ #define CONFIG_SYS_MEMTEST_START      PHYS_SDRAM_1    /* Memtest start address */
+ #define CONFIG_SYS_MEMTEST_END                (CONFIG_SYS_MEMTEST_START + SZ_4M)
+ #define CONFIG_SYS_SDRAM_CLK          400
+ /*
+  * U-Boot general configurations
+  */
+ #define CONFIG_SYS_LONGHELP
+ #define CONFIG_SYS_PROMPT             "TX53 U-Boot > "
+ #define CONFIG_SYS_CBSIZE             2048    /* Console I/O buffer size */
+ #define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+ #define CONFIG_SYS_MAXARGS            256     /* Max number of command args */
+ #define CONFIG_SYS_BARGSIZE           CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+ #define CONFIG_VERSION_VARIABLE                       /* U-BOOT version */
+ #define CONFIG_AUTO_COMPLETE                  /* Command auto complete */
+ #define CONFIG_CMDLINE_EDITING                        /* Command history etc */
+ #define CONFIG_SYS_64BIT_VSPRINTF
 -#define CONFIG_OF_LIBFDT
 -#define CONFIG_OF_BOARD_SETUP
+ /*
+  * Flattened Device Tree (FDT) support
+ */
 -#define CONFIG_HW_WATCHDOG
+ /*
+  * Boot Linux
+  */
+ #define xstr(s)                               str(s)
+ #define str(s)                                #s
+ #define __pfx(x, s)                   (x##s)
+ #define _pfx(x, s)                    __pfx(x, s)
+ #define CONFIG_CMDLINE_TAG
+ #define CONFIG_SETUP_MEMORY_TAGS
+ #define CONFIG_BOOTDELAY              3
+ #define CONFIG_ZERO_BOOTDELAY_CHECK
+ #define CONFIG_SYS_AUTOLOAD           "no"
+ #define CONFIG_BOOTFILE                       "uImage"
+ #define CONFIG_BOOTARGS                       "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+ #define CONFIG_BOOTCOMMAND            "run bootcmd_${boot_mode} bootm_cmd"
+ #define CONFIG_LOADADDR                       78000000
+ #define CONFIG_FDTADDR                        71000000
+ #define CONFIG_SYS_LOAD_ADDR          _pfx(0x, CONFIG_LOADADDR)
+ #define CONFIG_SYS_FDT_ADDR           _pfx(0x, CONFIG_FDTADDR)
+ #define CONFIG_U_BOOT_IMG_SIZE                SZ_1M
 -#define CONFIG_FDT_FIXUP_PARTITIONS
+ #ifndef CONFIG_SYS_LVDS_IF
+ #define DEFAULT_VIDEO_MODE            "VGA"
+ #else
+ #define DEFAULT_VIDEO_MODE            "HSD100PXN1"
+ #endif
+ /*
+  * Extra Environment Settings
+  */
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=800\0"                                                 \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=" DEFAULT_VIDEO_MODE "\0"
+ #define MTD_NAME                      "mxc_nand"
+ #define MTDIDS_DEFAULT                        "nand0=" MTD_NAME
 -#define CONFIG_CMD_CACHE
 -#define CONFIG_CMD_MMC
 -#define CONFIG_CMD_NAND
 -#define CONFIG_CMD_MTDPARTS
 -#define CONFIG_CMD_BOOTCE
 -#define CONFIG_CMD_TIME
 -#define CONFIG_CMD_I2C
 -#define CONFIG_CMD_MEMTEST
+ /*
+  * U-Boot Commands
+  */
+ #include <config_cmd_default.h>
 -#define CONFIG_FEC_MXC
+ /*
+  * Serial Driver
+  */
+ #define CONFIG_MXC_UART
+ #define CONFIG_MXC_UART_BASE          UART1_BASE
+ #define CONFIG_BAUDRATE                       115200          /* Default baud rate */
+ #define CONFIG_SYS_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, }
+ #define CONFIG_SYS_CONSOLE_INFO_QUIET
+ /*
+  * GPIO driver
+  */
+ #define CONFIG_MXC_GPIO
+ /*
+  * Ethernet Driver
+  */
 -#define CONFIG_FEC_MXC_PHYADDR                0
 -#define CONFIG_PHYLIB
 -#define CONFIG_PHY_SMSC
 -#define CONFIG_MII
+ #ifdef CONFIG_FEC_MXC
+ #define IMX_FEC_BASE                  FEC_BASE_ADDR
 -#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+ #define CONFIG_FEC_XCV_TYPE           MII100
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_PING
+ #define CONFIG_CMD_MII
 -#define CONFIG_HARD_I2C
+ /* Add for working with "strict" DHCP server */
+ #define CONFIG_BOOTP_SUBNETMASK
+ #define CONFIG_BOOTP_GATEWAY
+ #define CONFIG_BOOTP_DNS
+ #endif
+ /*
+  * I2C Configs
+  */
+ #ifdef CONFIG_CMD_I2C
 -#define CONFIG_MTD_DEVICE
 -#define CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_NAND_MXC
+ #define CONFIG_I2C_MXC
+ #define CONFIG_SYS_I2C_BASE           I2C1_BASE_ADDR
+ #define CONFIG_SYS_I2C_MX6_PORT1
+ #define CONFIG_SYS_I2C_SPEED          400000
+ #define CONFIG_SYS_I2C_SLAVE          0x34
+ #endif
+ /*
+  * NAND flash driver
+  */
+ #ifdef CONFIG_CMD_NAND
 -#define CONFIG_CMD_NAND_TRIMFFS
+ #define CONFIG_MXC_NAND_REGS_BASE     NFC_BASE_ADDR_AXI
+ #define CONFIG_MXC_NAND_IP_REGS_BASE  NFC_BASE_ADDR
+ #define CONFIG_MXC_NAND_HWECC
 -#define CONFIG_SYS_NAND_USE_FLASH_BBT
+ #define CONFIG_SYS_NAND_MAX_CHIPS     0x1
+ #define CONFIG_SYS_MAX_NAND_DEVICE    0x1
+ #define CONFIG_SYS_NAND_5_ADDR_CYCLE
 -#define CONFIG_CMD_ROMUPDATE
+ #ifdef CONFIG_ENV_IS_IN_NAND
+ #define CONFIG_ENV_OVERWRITE
+ #define CONFIG_ENV_OFFSET             CONFIG_U_BOOT_IMG_SIZE
+ #define CONFIG_ENV_SIZE                       0x20000 /* 128 KiB */
+ #define CONFIG_ENV_RANGE              0x60000
+ #endif
+ #define CONFIG_SYS_NAND_BASE          0x00000000
 -#define CONFIG_ENV_IS_IN_MMC
+ #endif /* CONFIG_CMD_NAND */
+ /*
+  * MMC Driver
+  */
+ #ifdef CONFIG_CMD_MMC
+ #ifndef CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_MMC
 -#define CONFIG_GENERIC_MMC
 -#define CONFIG_FSL_ESDHC
+ #endif
+ #define CONFIG_SYS_FSL_ESDHC_ADDR     0
+ #define CONFIG_DOS_PARTITION
+ #define CONFIG_CMD_FAT
+ #define CONFIG_FAT_WRITE
+ #define CONFIG_CMD_EXT2
+ /*
+  * Environments on MMC
+  */
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ #define CONFIG_ENV_OVERWRITE
+ /* Associated with the MMC layout defined in mmcops.c */
+ #define CONFIG_ENV_OFFSET             SZ_1K
+ #define CONFIG_ENV_SIZE                       (SZ_128K - CONFIG_ENV_OFFSET)
+ #define CONFIG_DYNAMIC_MMC_DEVNO
+ #endif /* CONFIG_ENV_IS_IN_MMC */
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_ENV_OFFSET_REDUND
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89344k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #else
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89728k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+ #endif
+ #define CONFIG_SYS_SDRAM_BASE         PHYS_SDRAM_1
+ #define CONFIG_SYS_INIT_SP_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+ #ifdef CONFIG_CMD_IIM
+ #define CONFIG_FSL_IIM
+ #endif
+ #endif /* __CONFIG_H */
diff --combined include/configs/tx6.h
index 0000000000000000000000000000000000000000,22f4c1007acddd1bce8f7321ab238c397d883d1d..1e4af07a07a388830dc01dfc22c37225974210f7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,400 +1,349 @@@
 - * Copyright (C) 2012 <LW@KARO-electronics.de>
+ /*
 -#include <asm/sizes.h>
++ * Copyright (C) 2012-2015 <LW@KARO-electronics.de>
+  *
+  * SPDX-License-Identifier:      GPL-2.0
+  *
+  */
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
 -#ifndef CONFIG_TX6_REV
 -#define CONFIG_TX6_REV                        0x1             /* '1' would be converted to 'y' by define2mk.sed */
 -#endif
 -#define CONFIG_MX6
++#include <linux/sizes.h>
+ #include <asm/arch/imx-regs.h>
++#include "mx6_common.h"
+ /*
+  * Ka-Ro TX6 board - SoC configuration
+  */
 -#ifndef CONFIG_MFG
+ #define CONFIG_SYS_MX6_HCLK           24000000
+ #define CONFIG_SYS_MX6_CLK32          32768
+ #define CONFIG_SYS_HZ                 1000            /* Ticks per second */
+ #define CONFIG_SHOW_ACTIVITY
+ #define CONFIG_ARCH_CPU_INIT
+ #define CONFIG_DISPLAY_BOARDINFO
+ #define CONFIG_BOARD_LATE_INIT
+ #define CONFIG_BOARD_EARLY_INIT_F
++#define CONFIG_SYS_GENERIC_BOARD
 -#define LCD_BPP                               LCD_COLOR24
++#ifndef CONFIG_TX6_UBOOT_MFG
+ /* LCD Logo and Splash screen support */
+ #define CONFIG_LCD
+ #ifdef CONFIG_LCD
+ #define CONFIG_SPLASH_SCREEN
+ #define CONFIG_SPLASH_SCREEN_ALIGN
+ #define CONFIG_VIDEO_IPUV3
+ #define CONFIG_IPUV3_CLK              (CONFIG_SYS_SDRAM_CLK * 1000000 / 2)
+ #define CONFIG_LCD_LOGO
 -#endif /* CONFIG_MFG */
++#define LCD_BPP                               LCD_COLOR32
+ #define CONFIG_CMD_BMP
+ #define CONFIG_VIDEO_BMP_RLE8
+ #endif /* CONFIG_LCD */
 -#define CONFIG_SYS_NO_FLASH
++#endif /* CONFIG_TX6_UBOOT_MFG */
+ /*
+  * Memory configuration options
+  */
+ #define CONFIG_NR_DRAM_BANKS          0x1             /* # of SDRAM banks */
+ #define PHYS_SDRAM_1                  0x10000000      /* Base address of bank 1 */
+ #ifdef CONFIG_SYS_SDRAM_BUS_WIDTH
+ #define PHYS_SDRAM_1_WIDTH            CONFIG_SYS_SDRAM_BUS_WIDTH
++#elif defined(CONFIG_SYS_SDRAM_BUS_WIDTH_32)
++#define PHYS_SDRAM_1_WIDTH            32
++#elif defined(CONFIG_SYS_SDRAM_BUS_WIDTH_16)
++#define PHYS_SDRAM_1_WIDTH            16
+ #else
+ #define PHYS_SDRAM_1_WIDTH            64
+ #endif
+ #define PHYS_SDRAM_1_SIZE             (SZ_512M / 32 * PHYS_SDRAM_1_WIDTH)
+ #ifdef CONFIG_MX6Q
+ #define CONFIG_SYS_SDRAM_CLK          528
+ #else
+ #define CONFIG_SYS_SDRAM_CLK          400
+ #endif
+ #define CONFIG_STACKSIZE              SZ_128K
+ #define CONFIG_SYS_MALLOC_LEN         SZ_8M
+ #define CONFIG_SYS_MEMTEST_START      PHYS_SDRAM_1    /* Memtest start address */
+ #define CONFIG_SYS_MEMTEST_END                (CONFIG_SYS_MEMTEST_START + SZ_4M)
+ /*
+  * U-Boot general configurations
+  */
+ #define CONFIG_SYS_LONGHELP
+ #if defined(CONFIG_MX6Q)
+ #define CONFIG_SYS_PROMPT             "TX6Q U-Boot > "
+ #elif defined(CONFIG_MX6DL)
+ #define CONFIG_SYS_PROMPT             "TX6DL U-Boot > "
+ #elif defined(CONFIG_MX6S)
+ #define CONFIG_SYS_PROMPT             "TX6S U-Boot > "
+ #else
+ #error Unsupported i.MX6 processor variant
+ #endif
+ #define CONFIG_SYS_CBSIZE             2048    /* Console I/O buffer size */
+ #define CONFIG_SYS_PBSIZE                                             \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+ #define CONFIG_SYS_MAXARGS            256     /* Max number of command args */
+ #define CONFIG_SYS_BARGSIZE           CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+ #define CONFIG_VERSION_VARIABLE                       /* U-BOOT version */
+ #define CONFIG_AUTO_COMPLETE                  /* Command auto complete */
+ #define CONFIG_CMDLINE_EDITING                        /* Command history etc */
+ #define CONFIG_SYS_64BIT_VSPRINTF
 -#ifndef CONFIG_MFG
 -#define CONFIG_OF_LIBFDT
+ /*
+  * Flattened Device Tree (FDT) support
+ */
 -#ifndef CONFIG_NO_NAND
 -#define CONFIG_FDT_FIXUP_PARTITIONS
+ #ifdef CONFIG_OF_LIBFDT
 -#define CONFIG_OF_BOARD_SETUP
++#ifdef CONFIG_TX6_NAND
+ #endif
 -#endif /* CONFIG_MFG */
+ #endif /* CONFIG_OF_LIBFDT */
 -#ifndef CONFIG_MFG
+ /*
+  * Boot Linux
+  */
+ #define xstr(s)                               str(s)
+ #define str(s)                                #s
+ #define __pfx(x, s)                   (x##s)
+ #define _pfx(x, s)                    __pfx(x, s)
+ #define CONFIG_CMDLINE_TAG
+ #define CONFIG_INITRD_TAG
+ #define CONFIG_SETUP_MEMORY_TAGS
 -#ifndef CONFIG_MFG
++#ifndef CONFIG_TX6_UBOOT_MFG
+ #define CONFIG_BOOTDELAY              1
+ #else
+ #define CONFIG_BOOTDELAY              0
+ #endif
+ #define CONFIG_ZERO_BOOTDELAY_CHECK
+ #define CONFIG_SYS_AUTOLOAD           "no"
 -#endif /* CONFIG_MFG */
++#ifndef CONFIG_TX6_UBOOT_MFG
+ #define CONFIG_BOOTFILE                       "uImage"
+ #define CONFIG_BOOTARGS                       "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+ #define CONFIG_BOOTCOMMAND            "run bootcmd_${boot_mode} bootm_cmd"
+ #else
+ #define CONFIG_BOOTCOMMAND            "env import " xstr(CONFIG_BOOTCMD_MFG_LOADADDR) ";run bootcmd_mfg"
+ #define CONFIG_BOOTCMD_MFG_LOADADDR   10500000
+ #define CONFIG_DELAY_ENVIRONMENT
 -#define CONFIG_HW_WATCHDOG
++#endif /* CONFIG_TX6_UBOOT_MFG */
+ #define CONFIG_LOADADDR                       18000000
+ #define CONFIG_FDTADDR                        11000000
+ #define CONFIG_SYS_LOAD_ADDR          _pfx(0x, CONFIG_LOADADDR)
+ #define CONFIG_SYS_FDT_ADDR           _pfx(0x, CONFIG_FDTADDR)
 -#ifndef CONFIG_MFG
+ #ifndef CONFIG_SYS_LVDS_IF
+ #define DEFAULT_VIDEO_MODE            "VGA"
+ #else
+ #define DEFAULT_VIDEO_MODE            "HSD100PXN1"
+ #endif
+ /*
+  * Extra Environments
+  */
 -#endif /*  CONFIG_MFG */
++#ifndef CONFIG_TX6_UBOOT_MFG
+ #ifdef CONFIG_ENV_IS_NOWHERE
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "autoload=no\0"                                                 \
+       "bootdelay=-1\0"                                                \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"
+ #else
+ #define CONFIG_EXTRA_ENV_SETTINGS                                     \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       MMC_ROOT_STR                                                    \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       CONFIG_SYS_BOOT_CMD_NAND                                        \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=" CONFIG_SYS_DEFAULT_BOOT_MODE "\0"                  \
+       "cpu_clk=800\0"                                                 \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       CONFIG_SYS_FDTSAVE_CMD                                          \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       ROOTPART_UUID_STR                                               \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=" DEFAULT_VIDEO_MODE "\0"
+ #endif /*  CONFIG_ENV_IS_NOWHERE */
 -#ifndef CONFIG_NO_NAND
++#endif /*  CONFIG_TX6_UBOOT_MFG */
 -#define MMC_ROOT_STR " root=dev/mmcblk0p2 rootwait\0"
++#ifdef CONFIG_TX6_NAND
+ #define CONFIG_SYS_DEFAULT_BOOT_MODE "nand"
+ #define CONFIG_SYS_BOOT_CMD_NAND                                      \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs;nboot linux\0"
+ #define CONFIG_SYS_FDTSAVE_CMD                                                \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"
+ #define MTD_NAME                      "gpmi-nand"
+ #define MTDIDS_DEFAULT                        "nand0=" MTD_NAME
+ #define CONFIG_SYS_NAND_ONFI_DETECTION
 -#define CONFIG_SUPPORT_EMMC_BOOT
 -#define CONFIG_MMC_BOOT_DEV           0
++#define MMC_ROOT_STR " root=/dev/mmcblk0p2 rootwait\0"
+ #define ROOTPART_UUID_STR ""
+ #else
+ #define CONFIG_SYS_DEFAULT_BOOT_MODE "mmc"
+ #define CONFIG_SYS_BOOT_CMD_NAND ""
+ #define CONFIG_SYS_FDTSAVE_CMD                                                \
+       "fdtsave=mmc open 0 1;mmc write ${fdtaddr} "                    \
+       xstr(CONFIG_SYS_DTB_BLKNO) " 80;mmc close 0 1\0"
+ #define MMC_ROOT_STR " root=PARTUUID=${rootpart_uuid} rootwait\0"
+ #define ROOTPART_UUID_STR "rootpart_uuid=0cc66cc0-02\0"
+ #define MTD_NAME                      ""
+ #define MTDIDS_DEFAULT                        ""
 -#define CONFIG_CMD_CACHE
 -#define CONFIG_CMD_MMC
 -#ifndef CONFIG_NO_NAND
 -#define CONFIG_CMD_NAND
 -#define CONFIG_CMD_MTDPARTS
 -#endif
 -#define CONFIG_CMD_BOOTCE
 -#define CONFIG_CMD_BOOTZ
 -#define CONFIG_CMD_TIME
 -#define CONFIG_CMD_I2C
 -#define CONFIG_CMD_MEMTEST
++#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ #endif
++#endif /* CONFIG_TX6_NAND */
+ /*
+  * U-Boot Commands
+  */
+ #include <config_cmd_default.h>
 -#define CONFIG_FEC_MXC
+ /*
+  * Serial Driver
+  */
+ #define CONFIG_MXC_UART
+ #define CONFIG_MXC_UART_BASE          UART1_BASE
+ #define CONFIG_BAUDRATE                       115200          /* Default baud rate */
+ #define CONFIG_SYS_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200, }
+ #define CONFIG_SYS_CONSOLE_INFO_QUIET
+ /*
+  * GPIO driver
+  */
+ #define CONFIG_MXC_GPIO
+ /*
+  * Ethernet Driver
+  */
 -#define CONFIG_SYS_CACHELINE_SIZE     64
+ #ifdef CONFIG_FEC_MXC
+ /* This is required for the FEC driver to work with cache enabled */
+ #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
 -#define CONFIG_FEC_MXC_PHYADDR                0
 -#define CONFIG_PHYLIB
 -#define CONFIG_PHY_SMSC
 -#define CONFIG_MII
+ #define IMX_FEC_BASE                  ENET_BASE_ADDR
 -#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
 -#define CONFIG_CMD_MII
 -#define CONFIG_CMD_DHCP
 -#define CONFIG_CMD_PING
 -/* Add for working with "strict" DHCP server */
 -#define CONFIG_BOOTP_SUBNETMASK
 -#define CONFIG_BOOTP_GATEWAY
 -#define CONFIG_BOOTP_DNS
+ #define CONFIG_FEC_XCV_TYPE           RMII
 -#ifdef CONFIG_CMD_I2C
 -#define CONFIG_HARD_I2C
 -#define CONFIG_I2C_MXC
+ #endif
+ /*
+  * I2C Configs
+  */
 -#define CONFIG_SYS_I2C_MX6_PORT1
++#ifdef CONFIG_SYS_I2C
+ #define CONFIG_SYS_I2C_BASE           I2C1_BASE_ADDR
 -#endif
+ #define CONFIG_SYS_I2C_SPEED          400000
++#if defined(CONFIG_TX6_REV)
+ #if CONFIG_TX6_REV == 0x1
+ #define CONFIG_SYS_I2C_SLAVE          0x3c
+ #define CONFIG_LTC3676
+ #elif CONFIG_TX6_REV == 0x2
+ #define CONFIG_SYS_I2C_SLAVE          0x32
+ #define CONFIG_RN5T618
+ #elif CONFIG_TX6_REV == 0x3
+ #define CONFIG_SYS_I2C_SLAVE          0x33
+ #define CONFIG_RN5T567
+ #else
+ #error Unsupported TX6 module revision
+ #endif
 -#ifndef CONFIG_ENV_IS_NOWHERE
 -/* define one of the following options:
 -#define CONFIG_ENV_IS_IN_NAND
 -#define CONFIG_ENV_IS_IN_MMC
 -*/
 -#define CONFIG_ENV_IS_IN_NAND
 -#endif
++#endif /* CONFIG_TX6_REV */
++/* autodetect which PMIC is present to derive TX6_REV */
++#define CONFIG_LTC3676                        /* TX6_REV == 1 */
++#define CONFIG_RN5T567                        /* TX6_REV == 3 */
++#endif /* CONFIG_CMD_I2C */
 -#ifndef CONFIG_NO_NAND
 -#define CONFIG_MTD_DEVICE
 -#if 0
 -#define CONFIG_MTD_DEBUG
 -#define CONFIG_MTD_DEBUG_VERBOSE      4
 -#endif
 -#define CONFIG_NAND_MXS
 -#define CONFIG_NAND_MXS_NO_BBM_SWAP
 -#define CONFIG_APBH_DMA
 -#define CONFIG_APBH_DMA_BURST
 -#define CONFIG_APBH_DMA_BURST8
 -#define CONFIG_CMD_NAND_TRIMFFS
+ #define CONFIG_ENV_OVERWRITE
+ /*
+  * NAND flash driver
+  */
 -#define CONFIG_SYS_NAND_5_ADDR_CYCLE
 -#define CONFIG_SYS_NAND_USE_FLASH_BBT
++#ifdef CONFIG_TX6_NAND
+ #define CONFIG_SYS_MXS_DMA_CHANNEL    4
+ #define CONFIG_SYS_MAX_FLASH_BANKS    0x1
+ #define CONFIG_SYS_NAND_MAX_CHIPS     0x1
+ #define CONFIG_SYS_MAX_NAND_DEVICE    0x1
 -#define CONFIG_CMD_ROMUPDATE
+ #define CONFIG_SYS_NAND_BASE          0x00000000
 -#endif /* CONFIG_NO_NAND */
++#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+ #define CONFIG_ENV_OFFSET             (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+ #define CONFIG_ENV_SIZE                       SZ_128K
+ #define CONFIG_ENV_RANGE              (3 * CONFIG_SYS_NAND_BLOCK_SIZE)
+ #else
+ #undef CONFIG_ENV_IS_IN_NAND
 -#ifdef CONFIG_CMD_MMC
 -#define CONFIG_MMC
 -#define CONFIG_GENERIC_MMC
 -#define CONFIG_FSL_ESDHC
 -#define CONFIG_FSL_USDHC
++#endif /* CONFIG_TX6_NAND */
+ #ifdef CONFIG_ENV_OFFSET_REDUND
+ #define CONFIG_SYS_ENV_PART_STR               xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"                                                        \
+       xstr(CONFIG_SYS_ENV_PART_SIZE)                                  \
+       "(env2),"
+ #define CONFIG_SYS_USERFS_PART_STR    xstr(CONFIG_SYS_USERFS_PART_SIZE) "(userfs)"
+ #else
+ #define CONFIG_SYS_ENV_PART_STR               xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"
+ #define CONFIG_SYS_USERFS_PART_STR    xstr(CONFIG_SYS_USERFS_PART_SIZE2) "(userfs)"
+ #endif /* CONFIG_ENV_OFFSET_REDUND */
+ /*
+  * MMC Driver
+  */
 -
++#ifdef CONFIG_FSL_ESDHC
+ #define CONFIG_SYS_FSL_ESDHC_ADDR     0
 -#ifndef CONFIG_NO_NAND
++#endif
++#ifdef CONFIG_CMD_MMC
+ #define CONFIG_DOS_PARTITION
+ #define CONFIG_CMD_FAT
+ #define CONFIG_FAT_WRITE
+ #define CONFIG_CMD_EXT2
+ /*
+  * Environments on MMC
+  */
+ #ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ #define CONFIG_SYS_MMC_ENV_PART               0x1
+ #define CONFIG_DYNAMIC_MMC_DEVNO
+ #endif /* CONFIG_ENV_IS_IN_MMC */
+ #else
+ #undef CONFIG_ENV_IS_IN_MMC
+ #endif /* CONFIG_CMD_MMC */
+ #ifdef CONFIG_ENV_IS_NOWHERE
+ #undef CONFIG_ENV_SIZE
+ #define CONFIG_ENV_SIZE                       SZ_4K
+ #endif
++#ifdef CONFIG_TX6_NAND
+ #define MTDPARTS_DEFAULT              "mtdparts=" MTD_NAME ":"        \
+       xstr(CONFIG_SYS_U_BOOT_PART_SIZE)                               \
+       "@" xstr(CONFIG_SYS_NAND_U_BOOT_OFFS)                           \
+       "(u-boot),"                                                     \
+       CONFIG_SYS_ENV_PART_STR                                         \
+       "6m(linux),32m(rootfs)," CONFIG_SYS_USERFS_PART_STR ","         \
+       xstr(CONFIG_SYS_DTB_PART_SIZE)                                  \
+       "@" xstr(CONFIG_SYS_NAND_DTB_OFFSET) "(dtb),"                   \
+       xstr(CONFIG_SYS_NAND_BBT_SIZE)                                  \
+       "@" xstr(CONFIG_SYS_NAND_BBT_OFFSET) "(bbt)ro"
+ #else
+ #define MTDPARTS_DEFAULT              ""
+ #endif
+ #define CONFIG_SYS_SDRAM_BASE         PHYS_SDRAM_1
+ #define CONFIG_SYS_INIT_SP_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+ #endif /* __CONFIG_H */
diff --combined include/fsl_esdhc.h
index c1b6648591e410e23d13a8b88aa27cdb8233efdb,0da20092f3a037fd4e8364b8ac776f1414efaed1..29bfe28801b86ab8c0912513d99e13c6993bb241
  #ifndef  __FSL_ESDHC_H__
  #define       __FSL_ESDHC_H__
  
+ #include <linux/compat.h>
  #include <asm/errno.h>
  #include <asm/byteorder.h>
  
 +/* needed for the mmc_cfg definition */
 +#include <mmc.h>
 +
  /* FSL eSDHC-specific constants */
  #define SYSCTL                        0x0002e02c
  #define SYSCTL_INITA          0x08000000
  #define ESDHC_HOSTCAPBLT_HSS  0x00200000
  
  struct fsl_esdhc_cfg {
-       u32     esdhc_base;
+       void __iomem *esdhc_base;
        u32     sdhc_clk;
        u8      max_bus_width;
 +      struct mmc_config cfg;
  };
  
  /* Select the correct accessors depending on endianess */
 -#if __BYTE_ORDER == __LITTLE_ENDIAN
 +#if defined CONFIG_SYS_FSL_ESDHC_LE
 +#define esdhc_read32          in_le32
 +#define esdhc_write32         out_le32
 +#define esdhc_clrsetbits32    clrsetbits_le32
 +#define esdhc_clrbits32               clrbits_le32
 +#define esdhc_setbits32               setbits_le32
 +#elif defined(CONFIG_SYS_FSL_ESDHC_BE)
 +#define esdhc_read32            in_be32
 +#define esdhc_write32           out_be32
 +#define esdhc_clrsetbits32      clrsetbits_be32
 +#define esdhc_clrbits32         clrbits_be32
 +#define esdhc_setbits32         setbits_be32
 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
  #define esdhc_read32          in_le32
  #define esdhc_write32         out_le32
  #define esdhc_clrsetbits32    clrsetbits_le32
@@@ -198,7 -183,5 +199,7 @@@ void fdt_fixup_esdhc(void *blob, bd_t *
  static inline int fsl_esdhc_mmc_init(bd_t *bis) { return -ENOSYS; }
  static inline void fdt_fixup_esdhc(void *blob, bd_t *bd) {}
  #endif /* CONFIG_FSL_ESDHC */
 +void __noreturn mmc_boot(void);
 +void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst);
  
  #endif  /* __FSL_ESDHC_H__ */
diff --combined include/ipu.h
index 091b58fb47bfccfa4bc30bfdd9e87006bbafa438,b8cf52147a32d38732a161b7a63c894d6c5dba90..b1143a42703bea06da690667e9df211f10b5dc92
@@@ -4,68 -4,25 +4,25 @@@
   * (C) Copyright 2010
   * Stefano Babic, DENX Software Engineering, sbabic@denx.de
   *
-  * Linux IPU driver for MX51:
+  * Linux IPU driver:
   *
-  * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+  * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
   *
   * SPDX-License-Identifier:   GPL-2.0+
   */
  
- #ifndef __ASM_ARCH_IPU_H__
- #define __ASM_ARCH_IPU_H__
+ #ifndef __IPU_H__
+ #define __IPU_H__
  
  #include <linux/types.h>
- #include <ipu_pixfmt.h>
+ #include <linux/list.h>
+ #include <linux/fb.h>
+ struct clk;
  
  #define IDMA_CHAN_INVALID     0xFF
  #define HIGH_RESOLUTION_WIDTH 1024
  
- struct clk {
-       const char *name;
-       int id;
-       /* Source clock this clk depends on */
-       struct clk *parent;
-       /* Secondary clock to enable/disable with this clock */
-       struct clk *secondary;
-       /* Current clock rate */
-       unsigned long rate;
-       /* Reference count of clock enable/disable */
-       __s8 usecount;
-       /* Register bit position for clock's enable/disable control. */
-       u8 enable_shift;
-       /* Register address for clock's enable/disable control. */
-       void *enable_reg;
-       u32 flags;
-       /*
-        * Function ptr to recalculate the clock's rate based on parent
-        * clock's rate
-        */
-       void (*recalc) (struct clk *);
-       /*
-        * Function ptr to set the clock to a new rate. The rate must match a
-        * supported rate returned from round_rate. Leave blank if clock is not
-       * programmable
-        */
-       int (*set_rate) (struct clk *, unsigned long);
-       /*
-        * Function ptr to round the requested clock rate to the nearest
-        * supported rate that is less than or equal to the requested rate.
-        */
-       unsigned long (*round_rate) (struct clk *, unsigned long);
-       /*
-        * Function ptr to enable the clock. Leave blank if clock can not
-        * be gated.
-        */
-       int (*enable) (struct clk *);
-       /*
-        * Function ptr to disable the clock. Leave blank if clock can not
-        * be gated.
-        */
-       void (*disable) (struct clk *);
-       /* Function ptr to set the parent clock of the clock. */
-       int (*set_parent) (struct clk *, struct clk *);
- };
  /*
   * Enumeration of Synchronous (Memory-less) panel types
   */
@@@ -74,6 -31,51 +31,51 @@@ typedef enum 
        IPU_PANEL_TFT,
  } ipu_panel_t;
  
+ /*  IPU Pixel format definitions */
+ #define fourcc(a, b, c, d)\
+       (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+ /*
+  * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
+  * the same used by V4L2 API.
+  */
+ #define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0')
+ #define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1')
+ #define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6')
+ #define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8')
+ #define IPU_PIX_FMT_RGB332  fourcc('R', 'G', 'B', '1')        /*<  8  RGB-3-3-2    */
+ #define IPU_PIX_FMT_RGB555  fourcc('R', 'G', 'B', 'O')        /*< 16  RGB-5-5-5    */
+ #define IPU_PIX_FMT_RGB565  fourcc('R', 'G', 'B', 'P')        /*< 1 6  RGB-5-6-5   */
+ #define IPU_PIX_FMT_RGB666  fourcc('R', 'G', 'B', '6')        /*< 18  RGB-6-6-6    */
+ #define IPU_PIX_FMT_BGR666  fourcc('B', 'G', 'R', '6')        /*< 18  BGR-6-6-6    */
+ #define IPU_PIX_FMT_BGR24   fourcc('B', 'G', 'R', '3')        /*< 24  BGR-8-8-8    */
+ #define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3')        /*< 24  RGB-8-8-8    */
+ #define IPU_PIX_FMT_BGR32   fourcc('B', 'G', 'R', '4')        /*< 32  BGR-8-8-8-8  */
+ #define IPU_PIX_FMT_BGRA32  fourcc('B', 'G', 'R', 'A')        /*< 32  BGR-8-8-8-8  */
+ #define IPU_PIX_FMT_RGB32   fourcc('R', 'G', 'B', '4')        /*< 32  RGB-8-8-8-8  */
+ #define IPU_PIX_FMT_RGBA32  fourcc('R', 'G', 'B', 'A')        /*< 32  RGB-8-8-8-8  */
+ #define IPU_PIX_FMT_ABGR32  fourcc('A', 'B', 'G', 'R')        /*< 32  ABGR-8-8-8-8 */
+ /* YUV Interleaved Formats */
+ #define IPU_PIX_FMT_YUYV    fourcc('Y', 'U', 'Y', 'V')        /*< 16 YUV 4:2:2 */
+ #define IPU_PIX_FMT_UYVY    fourcc('U', 'Y', 'V', 'Y')        /*< 16 YUV 4:2:2 */
+ #define IPU_PIX_FMT_Y41P    fourcc('Y', '4', '1', 'P')        /*< 12 YUV 4:1:1 */
+ #define IPU_PIX_FMT_YUV444  fourcc('Y', '4', '4', '4')        /*< 24 YUV 4:4:4 */
+ /* two planes -- one Y, one Cb + Cr interleaved  */
+ #define IPU_PIX_FMT_NV12    fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
+ #define IPU_PIX_FMT_GREY    fourcc('G', 'R', 'E', 'Y')        /*< 8  Greyscale */
+ #define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9')        /*< 9  YVU 4:1:0 */
+ #define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9')        /*< 9  YUV 4:1:0 */
+ #define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2')        /*< 12 YVU 4:2:0 */
+ #define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0')        /*< 12 YUV 4:2:0 */
+ #define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2')       /*< 12 YUV 4:2:0 */
+ #define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6')        /*< 16 YVU 4:2:2 */
+ #define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P')        /*< 16 YUV 4:2:2 */
  /*
   * IPU Driver channels definitions.
   * Note these are different from IDMA channels
@@@ -119,14 -121,25 +121,25 @@@ typedef enum 
   * Enumeration of types of buffers for a logical channel.
   */
  typedef enum {
-       IPU_OUTPUT_BUFFER = 0,  /*< Buffer for output from IPU */
-       IPU_ALPHA_IN_BUFFER = 1,        /*< Buffer for input to IPU */
-       IPU_GRAPH_IN_BUFFER = 2,        /*< Buffer for input to IPU */
-       IPU_VIDEO_IN_BUFFER = 3,        /*< Buffer for input to IPU */
+       IPU_OUTPUT_BUFFER = 0,          /* Buffer for output from IPU */
+       IPU_ALPHA_IN_BUFFER = 1,        /* Buffer for input to IPU */
+       IPU_GRAPH_IN_BUFFER = 2,        /* Buffer for input to IPU */
+       IPU_VIDEO_IN_BUFFER = 3,        /* Buffer for input to IPU */
        IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
        IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
  } ipu_buffer_t;
  
+ /*
+  * Enumeration of version of IPU V3 .
+  */
+ typedef enum {
+       IPUV3_HW_REV_IPUV3DEX = 2,      /* IPUv3D, IPUv3E  IPUv3EX  */
+       IPUV3_HW_REV_IPUV3M = 3,        /* IPUv3M */
+       IPUV3_HW_REV_IPUV3H = 4,        /* IPUv3H */
+ } ipu3_hw_rev_t;
  #define IPU_PANEL_SERIAL              1
  #define IPU_PANEL_PARALLEL            2
  
@@@ -175,14 -188,6 +188,14 @@@ typedef union 
        } mem_dp_fg_sync;
  } ipu_channel_params_t;
  
 +/*
 + * Enumeration of IPU interrupts.
 + */
 +enum ipu_irq_line {
 +      IPU_IRQ_DP_SF_END = 448 + 3,
 +      IPU_IRQ_DC_FC_1 = 448 + 9,
 +};
 +
  /*
   * Bitfield of Display Interface signal polarities.
   */
@@@ -206,7 -211,19 +219,19 @@@ typedef enum 
        YUV
  } ipu_color_space_t;
  
+ typedef enum {
+       DI_PCLK_PLL3,
+       DI_PCLK_LDB,
+       DI_PCLK_TVE
+ } ipu_di_clk_parent_t;
  /* Common IPU API */
+ int ipuv3_fb_init(struct fb_videomode *mode, int di,
+               unsigned int interface_pix_fmt,
+               ipu_di_clk_parent_t di_clk_parent,
+               unsigned long di_clk_val, int bpp);
+ void ipuv3_fb_shutdown(void);
  int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params);
  void ipu_uninit_channel(ipu_channel_t channel);
  
@@@ -242,7 -259,7 +267,7 @@@ int32_t ipu_disp_set_color_key(ipu_chan
  
  uint32_t bytes_per_pixel(uint32_t fmt);
  
void clk_enable(struct clk *clk);
int clk_enable(struct clk *clk);
  void clk_disable(struct clk *clk);
  u32 clk_get_rate(struct clk *clk);
  int clk_set_rate(struct clk *clk, unsigned long rate);
@@@ -252,7 -269,7 +277,7 @@@ int clk_get_usecount(struct clk *clk)
  struct clk *clk_get_parent(struct clk *clk);
  
  void ipu_dump_registers(void);
- int ipu_probe(void);
+ int ipu_probe(int di, ipu_di_clk_parent_t di_clk_parent, int di_clk_val);
  
  void ipu_dmfc_init(int dmfc_type, int first);
  void ipu_init_dc_mappings(void);
@@@ -266,4 -283,4 +291,4 @@@ void ipu_dp_uninit(ipu_channel_t channe
  void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap);
  ipu_color_space_t format_to_colorspace(uint32_t fmt);
  
- #endif
+ #endif /* __IPU_H */
diff --combined include/lcd.h
index 020d8800e9e6437fb6af4c70f64518c8f9b66e38,c167946eb222d23b963d262aa303319d972a888d..032308a657c91c5c265ec044029a271878350ab0
@@@ -1,4 -1,6 +1,6 @@@
  /*
+  * Copyright (C) 2004-2010 Freescale Semiconductor, Inc.
+  *
   * MPC823 and PXA LCD Controller
   *
   * Modeled after video interface by Paolo Scaffardi
@@@ -7,7 -9,7 +9,7 @@@
   * (C) Copyright 2001
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
 - * SPDX-License-Identifier:   GPL-2.0+ 
 + * SPDX-License-Identifier:   GPL-2.0+
   */
  
  #ifndef _LCD_H_
@@@ -26,6 -28,8 +28,6 @@@ void lcd_enable(void)
  void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue);
  void lcd_initcolregs(void);
  
 -int lcd_getfgcolor(void);
 -
  /* gunzip_bmp used if CONFIG_VIDEO_BMP_GZIP */
  struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
                             void **alloc_addr);
@@@ -221,8 -225,6 +223,8 @@@ typedef struct vidinfo 
        unsigned int logo_on;
        unsigned int logo_width;
        unsigned int logo_height;
 +      int logo_x_offset;
 +      int logo_y_offset;
        unsigned long logo_addr;
        unsigned int rgb_mode;
        unsigned int resolution;
@@@ -250,12 -252,15 +252,15 @@@ typedef struct vidinfo 
        void    *priv;          /* Pointer to driver-specific data */
  } vidinfo_t;
  
 -#endif /* CONFIG_MPC823, CONFIG_CPU_PXA25X, CONFIG_MCC200, CONFIG_ATMEL_LCD */
 +#endif /* CONFIG_MPC823, CONFIG_CPU_PXA25X, CONFIG_ATMEL_LCD */
  
  extern vidinfo_t panel_info;
  
  /* Video functions */
  
+ void  lcd_disable(void);
+ void  lcd_panel_disable(void);
  void  lcd_putc(const char c);
  void  lcd_puts(const char *s);
  void  lcd_printf(const char *fmt, ...);
@@@ -307,9 -312,6 +312,9 @@@ int lcd_get_size(int *line_length)
  int lcd_dt_simplefb_add_node(void *blob);
  int lcd_dt_simplefb_enable_existing_node(void *blob);
  
 +/* Update the LCD / flush the cache */
 +void lcd_sync(void);
 +
  /************************************************************************/
  /* ** BITMAP DISPLAY SUPPORT                                          */
  /************************************************************************/
  #define LCD_COLOR4    2
  #define LCD_COLOR8    3
  #define LCD_COLOR16   4
 -#define LCD_COLOR24   5
 -
 +#define LCD_COLOR32   5
  /*----------------------------------------------------------------------*/
  #if defined(CONFIG_LCD_INFO_BELOW_LOGO)
  # define LCD_INFO_X           0
  # define CONSOLE_COLOR_GREY   14
  # define CONSOLE_COLOR_WHITE  15      /* Must remain last / highest   */
  
- #else
 +#elif LCD_BPP == LCD_COLOR32
 +/*
 + * 32bpp color definitions
 + */
 +# define CONSOLE_COLOR_RED    0x00ff0000
 +# define CONSOLE_COLOR_GREEN  0x0000ff00
 +# define CONSOLE_COLOR_YELLOW 0x00ffff00
 +# define CONSOLE_COLOR_BLUE   0x000000ff
 +# define CONSOLE_COLOR_MAGENTA        0x00ff00ff
 +# define CONSOLE_COLOR_CYAN   0x0000ffff
 +# define CONSOLE_COLOR_GREY   0x00aaaaaa
 +# define CONSOLE_COLOR_BLACK  0x00000000
 +# define CONSOLE_COLOR_WHITE  0x00ffffff      /* Must remain last / highest*/
 +# define NBYTES(bit_code)     (NBITS(bit_code) >> 3)
 +
+ #elif LCD_BPP == LCD_COLOR16
  
  /*
   * 16bpp color definitions
   */
  # define CONSOLE_COLOR_BLACK  0x0000
+ # define CONSOLE_COLOR_RED    0xf800
+ # define CONSOLE_COLOR_GREEN  0x07e0
+ # define CONSOLE_COLOR_YELLOW 0xffe0
+ # define CONSOLE_COLOR_BLUE   0x001f
+ # define CONSOLE_COLOR_MAGENTA        0xf81f
+ # define CONSOLE_COLOR_CYAN   0x07ff
+ # define CONSOLE_COLOR_GREY   0xcccc
  # define CONSOLE_COLOR_WHITE  0xffff  /* Must remain last / highest   */
  
 -#elif LCD_BPP == LCD_COLOR24
 -/*
 - * 16bpp color definitions
 - */
 -# define CONSOLE_COLOR_BLACK  0x00000000
 -# define CONSOLE_COLOR_RED    0x00ff0000
 -# define CONSOLE_COLOR_GREEN  0x0000ff00
 -# define CONSOLE_COLOR_YELLOW 0x00ffff00
 -# define CONSOLE_COLOR_BLUE   0x000000ff
 -# define CONSOLE_COLOR_MAGENTA        0x00ff00ff
 -# define CONSOLE_COLOR_CYAN   0x0000ffff
 -# define CONSOLE_COLOR_GREY   0x00cccccc
 -# define CONSOLE_COLOR_WHITE  0x00ffffff      /* Must remain last / highest   */
+ #else
+ #error Invalid LCD_BPP setting
  #endif /* color definitions */
  
  /************************************************************************/
diff --combined include/nand.h
index 15e31ab538ba5e84c09ae512b7f5a2dad0c21c47,2b62ef777e7df87917194f79bb6b7a8db037daf1..3c8dea5f8709a23ee5ce4a4bc1fcebd26626bb08
  
  #include <config.h>
  
--/*
-- * All boards using a given driver must convert to self-init
-- * at the same time, so do it here.  When all drivers are
-- * converted, this will go away.
-- */
- #ifdef CONFIG_SPL_BUILD
- #if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_FSL_IFC)
- #define CONFIG_SYS_NAND_SELF_INIT
- #endif
- #else
--#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)\
-       || defined(CONFIG_NAND_FSL_IFC)
 -      || defined(CONFIG_NAND_FSL_IFC) || defined(CONFIG_NAND_MXC)
--#define CONFIG_SYS_NAND_SELF_INIT
- #endif
--#endif
--
  extern void nand_init(void);
  
  #include <linux/compat.h>
@@@ -167,4 -161,3 +151,4 @@@ __attribute__((noreturn)) void nand_boo
  #define ENV_OFFSET_SIZE 8
  int get_nand_env_oob(nand_info_t *nand, unsigned long *result);
  #endif
 +int spl_nand_erase_one(int block, int page);
diff --combined include/net.h
index 18d279ebe737da5ac87cf891d509b44efb1ece94,faa4b50cd689d90e2ad4ad179b711910462fc3fb..0dd721604fd3d6f4eb70bf2c866c7895ecb76ef9
@@@ -3,7 -3,7 +3,7 @@@
   *
   *    Copyright 1994 - 2000 Neil Russell.
   *    (See License)
 - *
 + *    SPDX-License-Identifier:        GPL-2.0
   *
   * History
   *    9/16/00   bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
@@@ -89,7 -89,7 +89,7 @@@ struct eth_device 
        int  (*recv) (struct eth_device *);
        void (*halt) (struct eth_device *);
  #ifdef CONFIG_MCAST_TFTP
 -      int (*mcast) (struct eth_device *, u32 ip, u8 set);
 +      int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set);
  #endif
        int  (*write_hwaddr) (struct eth_device *);
        struct eth_device *next;
@@@ -130,6 -130,23 +130,6 @@@ extern int eth_setenv_enetaddr(char *na
  extern int eth_getenv_enetaddr_by_index(const char *base_name, int index,
                                        uchar *enetaddr);
  
 -#ifdef CONFIG_RANDOM_MACADDR
 -/*
 - * The u-boot policy does not allow hardcoded ethernet addresses. Under the
 - * following circumstances a random generated address is allowed:
 - *  - in emergency cases, where you need a working network connection to set
 - *    the ethernet address.
 - *    Eg. you want a rescue boot and don't have a serial port to access the
 - *    CLI to set environment variables.
 - *
 - * In these cases, we generate a random locally administered ethernet address.
 - *
 - * Args:
 - *  enetaddr - returns 6 byte hardware address
 - */
 -extern void eth_random_enetaddr(uchar *enetaddr);
 -#endif
 -
  extern int usb_eth_initialize(bd_t *bi);
  extern int eth_init(bd_t *bis);                       /* Initialize the device */
  extern int eth_send(void *packet, int length);           /* Send a packet */
@@@ -340,7 -357,7 +340,7 @@@ struct icmp_hdr 
                } echo;
                ulong   gateway;
                struct {
 -                      ushort  __unused;
 +                      ushort  unused;
                        ushort  mtu;
                } frag;
                uchar data[0];
@@@ -420,7 -437,7 +420,7 @@@ extern int         NetRestartWrap;         /* Tried a
  
  enum proto_t {
        BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-       TFTPSRV, TFTPPUT, LINKLOCAL
+       TFTPSRV, TFTPPUT, LINKLOCAL, BOOTME
  };
  
  /* from net/net.c */
@@@ -556,6 -573,9 +556,9 @@@ static inline void eth_set_last_protoco
        net_loop_last_protocol = protocol;
  #endif
  }
+ #ifdef CONFIG_CMD_BOOTCE
+ void BootmeStart(void);
+ #endif
  
  /*
   * Check if autoload is enabled. If so, use either NFS or TFTP to download
@@@ -657,25 -677,6 +660,25 @@@ static inline int is_valid_ether_addr(c
        return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
  }
  
 +/**
 + * eth_random_addr - Generate software assigned random Ethernet address
 + * @addr: Pointer to a six-byte array containing the Ethernet address
 + *
 + * Generate a random Ethernet address (MAC) that is not multicast
 + * and has the local assigned bit set.
 + */
 +static inline void eth_random_addr(uchar *addr)
 +{
 +      int i;
 +      unsigned int seed = get_timer(0);
 +
 +      for (i = 0; i < 6; i++)
 +              addr[i] = rand_r(&seed);
 +
 +      addr[0] &= 0xfe;        /* clear multicast bit */
 +      addr[0] |= 0x02;        /* set local assignment bit (IEEE802) */
 +}
 +
  /* Convert an IP address to a string */
  extern void ip_to_string(IPaddr_t x, char *s);
  
diff --combined include/netdev.h
index 34651ab3779014ce6ec96a83b41acc0a96e60c00,a2f60b2135a4f796d342802bef7ef2e6ff965bdc..c3d3d6984a242e733da6d24ddbf8cb3ff389e285
@@@ -31,13 -31,12 +31,13 @@@ int altera_tse_initialize(u8 dev_num, i
  int at91emac_register(bd_t *bis, unsigned long iobase);
  int au1x00_enet_initialize(bd_t*);
  int ax88180_initialize(bd_t *bis);
 +int bcm_sf2_eth_register(bd_t *bis, u8 dev_num);
  int bfin_EMAC_initialize(bd_t *bis);
  int calxedaxgmac_initialize(u32 id, ulong base_addr);
  int cs8900_initialize(u8 dev_num, int base_addr);
  int davinci_emac_initialize(void);
  int dc21x4x_initialize(bd_t *bis);
 -int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface);
 +int designware_initialize(ulong base_addr, u32 interface);
  int dm9000_initialize(bd_t *bis);
  int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
  int e1000_initialize(bd_t *bis);
@@@ -55,6 -54,7 +55,6 @@@ int ftmac100_initialize(bd_t *bits)
  int ftmac110_initialize(bd_t *bits);
  int greth_initialize(bd_t *bis);
  void gt6426x_eth_initialize(bd_t *bis);
 -int inca_switch_initialize(bd_t *bis);
  int ks8695_eth_initialize(void);
  int ks8851_mll_initialize(u8 dev_num, int base_addr);
  int lan91c96_initialize(u8 dev_num, int base_addr);
@@@ -65,12 -65,12 +65,12 @@@ 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);
  int ns8382x_initialize(bd_t *bis);
  int pcnet_initialize(bd_t *bis);
 -int plb2800_eth_initialize(bd_t *bis);
  int ppc_4xx_eth_initialize (bd_t *bis);
  int rtl8139_initialize(bd_t *bis);
  int rtl8169_initialize(bd_t *bis);
@@@ -79,20 -79,17 +79,20 @@@ int sh_eth_initialize(bd_t *bis)
  int skge_initialize(bd_t *bis);
  int smc91111_initialize(u8 dev_num, int base_addr);
  int smc911x_initialize(u8 dev_num, int base_addr);
 -int sunxi_wemac_initialize(bd_t *bis);
 +int sunxi_emac_initialize(bd_t *bis);
 +int sunxi_gmac_initialize(bd_t *bis);
  int tsi108_eth_initialize(bd_t *bis);
  int uec_standard_init(bd_t *bis);
  int uli526x_initialize(bd_t *bis);
  int armada100_fec_register(unsigned long base_addr);
  int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
                                                        unsigned long dma_addr);
 +int xilinx_emaclite_of_init(const void *blob);
  int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
                                                        int txpp, int rxpp);
  int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
                                                unsigned long ctrl_addr);
 +int zynq_gem_of_init(const void *blob);
  int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio);
  /*
   * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
@@@ -216,4 -213,40 +216,40 @@@ int fec_probe(bd_t *bd, int dev_id, uin
  int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
  #endif
  
+ #ifdef CONFIG_DRIVER_TI_CPSW
+ enum {
+       CPSW_CTRL_VERSION_1 = 0, /* version1 devices */
+       CPSW_CTRL_VERSION_2      /* version2 devices */
+ };
+ struct cpsw_slave_data {
+       u32             slave_reg_ofs;
+       u32             sliver_reg_ofs;
+       int             phy_id;
+       int             phy_if;
+ };
+ struct cpsw_platform_data {
+       u32     mdio_base;
+       u32     cpsw_base;
+       int     mdio_div;
+       int     channels;       /* number of cpdma channels (symmetric) */
+       u32     cpdma_reg_ofs;  /* cpdma register offset                */
+       int     slaves;         /* number of slave cpgmac ports         */
+       u32     ale_reg_ofs;    /* address lookup engine reg offset     */
+       int     ale_entries;    /* ale table size                       */
+       u32     host_port_reg_ofs;      /* cpdma host port registers    */
+       u32     hw_stats_reg_ofs;       /* cpsw hw stats counters       */
+       u32     mac_control;
+       struct cpsw_slave_data  *slave_data;
+       void    (*control)(int enabled);
+       void    (*phy_init)(char *name, int addr);
+       u32     gigabit_en;     /* gigabit capable AND enabled          */
+       u32     host_port_num;
+       u8      version;
+ };
+ int cpsw_register(struct cpsw_platform_data *data);
+ #endif /* CONFIG_DRIVER_TI_CPSW */
  #endif /* _NETDEV_H_ */
diff --combined include/spl.h
index b2e5bf726f2b60d7d81d8bafb5a9ec8357749ff4,625785f022a63c269accd58977592a860df6fa0d..36e301ade41c33b1dfab7e721844aae869270a14
  #include <linux/compiler.h>
  #include <asm/spl.h>
  
 +
  /* Boot type */
  #define MMCSD_MODE_UNDEFINED  0
  #define MMCSD_MODE_RAW                1
 -#define MMCSD_MODE_FAT                2
 +#define MMCSD_MODE_FS         2
 +#define MMCSD_MODE_EMMCBOOT   3
  
  struct spl_image_info {
        const char *name;
@@@ -35,7 -33,6 +35,7 @@@ extern struct spl_image_info spl_image
  void preloader_console_init(void);
  u32 spl_boot_device(void);
  u32 spl_boot_mode(void);
 +void spl_set_header_raw_uboot(void);
  void spl_parse_image_header(const struct image_header *header);
  void spl_board_prepare_for_linux(void);
  void __noreturn jump_to_image_linux(void *arg);
@@@ -43,7 -40,7 +43,7 @@@ int spl_start_uboot(void)
  void spl_display_print(void);
  
  /* NAND SPL functions */
void spl_nand_load_image(void);
int spl_nand_load_image(void);
  
  /* OneNAND SPL functions */
  void spl_onenand_load_image(void);
@@@ -63,22 -60,6 +63,22 @@@ void spl_spi_load_image(void)
  /* Ethernet SPL functions */
  void spl_net_load_image(const char *device);
  
 +/* USB SPL functions */
 +void spl_usb_load_image(void);
 +
 +/* SATA SPL functions */
 +void spl_sata_load_image(void);
 +
 +/* SPL FAT image functions */
 +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);
 +
 +/* SPL EXT image functions */
 +int spl_load_image_ext(block_dev_desc_t *block_dev, int partition, const char *filename);
 +int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);
 +
  #ifdef CONFIG_SPL_BOARD_INIT
  void spl_board_init(void);
  #endif
diff --combined net/Makefile
index 942595021dad1cf3fccb27531bde72e20e0acd88,13917d0713f40f85c10a10d037380bb67720b521..d7f4e65f18fcbc94bb1f4aff33a19a0b58342b6e
@@@ -5,17 -5,40 +5,18 @@@
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
 -include $(TOPDIR)/config.mk
 -
 -# CFLAGS += -DDEBUG
 -
 -LIB   = $(obj)libnet.o
 -
 -COBJS-$(CONFIG_CMD_BOOTCE) += bootme.o
 -COBJS-$(CONFIG_CMD_NET)  += arp.o
 -COBJS-$(CONFIG_CMD_NET)  += bootp.o
 -COBJS-$(CONFIG_CMD_CDP)  += cdp.o
 -COBJS-$(CONFIG_CMD_DNS)  += dns.o
 -COBJS-$(CONFIG_CMD_NET)  += eth.o
 -COBJS-$(CONFIG_CMD_LINK_LOCAL) += link_local.o
 -COBJS-$(CONFIG_CMD_NET)  += net.o
 -COBJS-$(CONFIG_CMD_NFS)  += nfs.o
 -COBJS-$(CONFIG_CMD_PING) += ping.o
 -COBJS-$(CONFIG_CMD_RARP) += rarp.o
 -COBJS-$(CONFIG_CMD_SNTP) += sntp.o
 -COBJS-$(CONFIG_CMD_NET)  += tftp.o
 -
 -COBJS := $(sort $(COBJS-y))
 -SRCS  := $(COBJS:.o=.c)
 -OBJS  := $(addprefix $(obj),$(COBJS))
 -
 -all:  $(LIB)
 -
 -$(LIB):       $(obj).depend $(OBJS)
 -      $(call cmd_link_o_target, $(OBJS))
 -
 -#########################################################################
 -
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
 +#ccflags-y += -DDEBUG
 +
 +obj-$(CONFIG_CMD_NET)  += arp.o
++obj-$(CONFIG_CMD_BOOTCE) += bootme.o
 +obj-$(CONFIG_CMD_NET)  += bootp.o
 +obj-$(CONFIG_CMD_CDP)  += cdp.o
 +obj-$(CONFIG_CMD_DNS)  += dns.o
 +obj-$(CONFIG_CMD_NET)  += eth.o
 +obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o
 +obj-$(CONFIG_CMD_NET)  += net.o
 +obj-$(CONFIG_CMD_NFS)  += nfs.o
 +obj-$(CONFIG_CMD_PING) += ping.o
 +obj-$(CONFIG_CMD_RARP) += rarp.o
 +obj-$(CONFIG_CMD_SNTP) += sntp.o
 +obj-$(CONFIG_CMD_NET)  += tftp.o
diff --combined net/bootp.c
index 81066015f1c2ed28a4fb0ea1ec4bbeecec08047f,386e89b9d878dd6045c0501de1d8985533d88e45..5e835a31ad786ada52102b23907777d662046f3f
  #ifdef CONFIG_STATUS_LED
  #include <status_led.h>
  #endif
- #ifdef CONFIG_BOOTP_RANDOM_DELAY
+ #if defined(CONFIG_BOOTP_RANDOM_DELAY) || defined(CONFIG_BOOTP_RANDOM_ID)
  #include "net_rand.h"
  #endif
  
  #define BOOTP_VENDOR_MAGIC    0x63825363      /* RFC1048 Magic Cookie */
  
 -#define TIMEOUT               5000UL  /* Milliseconds before trying BOOTP again */
 +/*
 + * The timeout for the initial BOOTP/DHCP request used to be described by a
 + * counter of fixed-length timeout periods. TIMEOUT_COUNT represents
 + * that counter
 + *
 + * Now that the timeout periods are variable (exponential backoff and retry)
 + * we convert the timeout count to the absolute time it would have take to
 + * execute that many retries, and keep sending retry packets until that time
 + * is reached.
 + */
  #ifndef CONFIG_NET_RETRY_COUNT
  # define TIMEOUT_COUNT        5               /* # of timeouts before giving up */
  #else
  # define TIMEOUT_COUNT        (CONFIG_NET_RETRY_COUNT)
  #endif
 +#define TIMEOUT_MS    ((3 + (TIMEOUT_COUNT * 5)) * 1000)
  
  #define PORT_BOOTPS   67              /* BOOTP server UDP port */
  #define PORT_BOOTPC   68              /* BOOTP client UDP port */
  #define CONFIG_DHCP_MIN_EXT_LEN 64
  #endif
  
 -static ulong          BootpID;
 +#ifndef CONFIG_BOOTP_ID_CACHE_SIZE
 +#define CONFIG_BOOTP_ID_CACHE_SIZE 4
 +#endif
 +
 +ulong         bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
 +unsigned int  bootp_num_ids;
  int           BootpTry;
 +ulong         bootp_start;
 +ulong         bootp_timeout;
  
  #if defined(CONFIG_CMD_DHCP)
  static dhcp_state_t dhcp_state = INIT;
@@@ -82,30 -65,6 +82,30 @@@ static char *dhcpmsg2str(int type
  #endif
  #endif
  
 +static void bootp_add_id(ulong id)
 +{
 +      if (bootp_num_ids >= ARRAY_SIZE(bootp_ids)) {
 +              size_t size = sizeof(bootp_ids) - sizeof(id);
 +
 +              memmove(bootp_ids, &bootp_ids[1], size);
 +              bootp_ids[bootp_num_ids - 1] = id;
 +      } else {
 +              bootp_ids[bootp_num_ids] = id;
 +              bootp_num_ids++;
 +      }
 +}
 +
 +static bool bootp_match_id(ulong id)
 +{
 +      unsigned int i;
 +
 +      for (i = 0; i < bootp_num_ids; i++)
 +              if (bootp_ids[i] == id)
 +                      return true;
 +
 +      return false;
 +}
 +
  static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
  {
        struct Bootp_t *bp = (struct Bootp_t *) pkt;
                retval = -4;
        else if (bp->bp_hlen != HWL_ETHER)
                retval = -5;
 -      else if (NetReadLong((ulong *)&bp->bp_id) != BootpID)
 +      else if (!bootp_match_id(NetReadLong((ulong *)&bp->bp_id)))
                retval = -6;
  
        debug("Filtering pkt = %d\n", retval);
@@@ -145,6 -104,8 +145,6 @@@ static void BootpCopyNetParams(struct B
        if (tmp_ip != 0)
                NetCopyIP(&NetServerIP, &bp->bp_siaddr);
        memcpy(NetServerEther, ((struct ethernet_hdr *)NetRxPacket)->et_src, 6);
 -#endif
 -      NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
        if (strlen(bp->bp_file) > 0)
                copy_filename(BootFile, bp->bp_file, sizeof(BootFile));
  
         */
        if (*BootFile)
                setenv("bootfile", BootFile);
 +#endif
 +      NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
  }
  
  static int truncate_sz(const char *name, int maxlen, int curlen)
@@@ -368,21 -327,16 +368,21 @@@ BootpHandler(uchar *pkt, unsigned dest
  static void
  BootpTimeout(void)
  {
 -      if (BootpTry >= TIMEOUT_COUNT) {
 +      ulong time_taken = get_timer(bootp_start);
 +
 +      if (time_taken >= TIMEOUT_MS) {
  #ifdef CONFIG_BOOTP_MAY_FAIL
 -              puts("\nRetry count exceeded\n");
 +              puts("\nRetry time exceeded\n");
                net_set_state(NETLOOP_FAIL);
  #else
 -              puts("\nRetry count exceeded; starting again\n");
 +              puts("\nRetry time exceeded; starting again\n");
                NetStartAgain();
  #endif
        } else {
 -              NetSetTimeout(TIMEOUT, BootpTimeout);
 +              bootp_timeout *= 2;
 +              if (bootp_timeout > 2000)
 +                      bootp_timeout = 2000;
 +              NetSetTimeout(bootp_timeout, BootpTimeout);
                BootpRequest();
        }
  }
@@@ -485,7 -439,7 +485,7 @@@ static int DhcpExtended(u8 *e, int mess
                        *e++ = 17;
                        *e++ = 0;       /* type 0 - UUID */
  
 -                      uuid_str_to_bin(uuid, e);
 +                      uuid_str_to_bin(uuid, e, UUID_STR_FORMAT_STD);
                        e += 16;
                } else {
                        printf("Invalid pxeuuid: %s\n", uuid);
@@@ -643,14 -597,6 +643,14 @@@ static int BootpExtended(u8 *e
  }
  #endif
  
 +void BootpReset(void)
 +{
 +      bootp_num_ids = 0;
 +      BootpTry = 0;
 +      bootp_start = get_timer(0);
 +      bootp_timeout = 250;
 +}
 +
  void
  BootpRequest(void)
  {
        int extlen, pktlen, iplen;
        int eth_hdr_size;
  #ifdef CONFIG_BOOTP_RANDOM_DELAY
 -      ulong i, rand_ms;
 +      ulong rand_ms;
  #endif
 +      ulong BootpID;
  
        bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
  #if defined(CONFIG_CMD_DHCP)
                rand_ms = rand() >> 19;
  
        printf("Random delay: %ld ms...\n", rand_ms);
 -      for (i = 0; i < rand_ms; i++)
 -              udelay(1000); /*Wait 1ms*/
 +      mdelay(rand_ms);
  
  #endif        /* CONFIG_BOOTP_RANDOM_DELAY */
  
         *      Bootp ID is the lower 4 bytes of our ethernet address
         *      plus the current time in ms.
         */
+ #ifdef CONFIG_BOOTP_RANDOM_ID
+       BootpID = rand();
+ #else
        BootpID = ((ulong)NetOurEther[2] << 24)
                | ((ulong)NetOurEther[3] << 16)
                | ((ulong)NetOurEther[4] << 8)
                | (ulong)NetOurEther[5];
        BootpID += get_timer(0);
 -      BootpID  = htonl(BootpID);
 +      BootpID = htonl(BootpID);
 +      bootp_add_id(BootpID);
+ #endif
        NetCopyLong(&bp->bp_id, &BootpID);
  
        /*
        iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
        pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
        net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
 -      NetSetTimeout(SELECT_TIMEOUT, BootpTimeout);
 +      NetSetTimeout(bootp_timeout, BootpTimeout);
  
  #if defined(CONFIG_CMD_DHCP)
        dhcp_state = SELECTING;
@@@ -974,7 -923,7 +978,7 @@@ DhcpHandler(uchar *pkt, unsigned dest, 
                                                htonl(BOOTP_VENDOR_MAGIC))
                                DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
  
 -                      NetSetTimeout(TIMEOUT, BootpTimeout);
 +                      NetSetTimeout(5000, BootpTimeout);
                        DhcpSendRequestPkt(bp);
  #ifdef CONFIG_SYS_BOOTFILE_PREFIX
                }
                        /* Store net params from reply */
                        BootpCopyNetParams(bp);
                        dhcp_state = BOUND;
 -                      printf("DHCP client bound to address %pI4\n",
 -                              &NetOurIP);
 +                      printf("DHCP client bound to address %pI4 (%lu ms)\n",
 +                              &NetOurIP, get_timer(bootp_start));
                        bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
                                "bootp_stop");
  
diff --combined net/bootp.h
index 3b95a0a2ded87596636516c3b1b865aa79cf3aaf,a7117528a4f3c4ae299094912b6925d5ef1d305e..3ffbc51db3b1588855324de3dcd735ad903f3bee
@@@ -59,13 -59,11 +59,12 @@@ struct Bootp_t 
   */
  
  /* bootp.c */
- extern ulong  BootpID;                /* ID of cur BOOTP request      */
  extern char   BootFile[128];          /* Boot file name               */
  extern int    BootpTry;
  
  
  /* Send a BOOTP request */
 +extern void BootpReset(void);
  extern void BootpRequest(void);
  
  /****************** DHCP Support *********************/
@@@ -89,6 -87,8 +88,6 @@@ typedef enum { INIT
  #define DHCP_NAK      6
  #define DHCP_RELEASE  7
  
 -#define SELECT_TIMEOUT 3000UL /* Milliseconds to wait for offers */
 -
  /**********************************************************************/
  
  #endif /* __BOOTP_H__ */
diff --combined net/net.c
index 2bea07b3cdf671e4dc825b299ada89125f1b89c2,019d161bc760ec9df284642470212e0f6b4c69fb..30ecfcc403cfe0b168987d05e39db6e821e864f8
+++ b/net/net.c
@@@ -6,7 -6,6 +6,7 @@@
   *    Copyright 2000 Roland Borde
   *    Copyright 2000 Paolo Scaffardi
   *    Copyright 2000-2002 Wolfgang Denk, wd@denx.de
 + *    SPDX-License-Identifier:        GPL-2.0
   */
  
  /*
@@@ -208,8 -207,6 +208,8 @@@ static int net_check_prereq(enum proto_
  
  static int NetTryCount;
  
 +int __maybe_unused net_busy_flag;
 +
  /**********************************************************************/
  
  static int on_bootfile(const char *name, const char *value, enum env_op op,
@@@ -345,9 -342,6 +345,9 @@@ int NetLoop(enum proto_t protocol
                eth_init_state_only(bd);
  
  restart:
 +#ifdef CONFIG_USB_KEYBOARD
 +      net_busy_flag = 0;
 +#endif
        net_set_state(NETLOOP_CONTINUE);
  
        /*
  #endif
  #if defined(CONFIG_CMD_DHCP)
                case DHCP:
 -                      BootpTry = 0;
 +                      BootpReset();
                        NetOurIP = 0;
                        DhcpRequest();          /* Basically same as BOOTP */
                        break;
  #endif
  
                case BOOTP:
 -                      BootpTry = 0;
 +                      BootpReset();
                        NetOurIP = 0;
                        BootpRequest();
                        break;
                        CDPStart();
                        break;
  #endif
 -#ifdef CONFIG_NETCONSOLE
 +#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
                case NETCONS:
                        NcStart();
                        break;
                case LINKLOCAL:
                        link_local_start();
                        break;
+ #endif
+ #if defined(CONFIG_CMD_BOOTCE)
+               case BOOTME:
+                       BootmeStart();
+                       break;
  #endif
                default:
                        break;
                status_led_set(STATUS_LED_RED, STATUS_LED_ON);
  #endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
  #endif /* CONFIG_MII, ... */
 +#ifdef CONFIG_USB_KEYBOARD
 +      net_busy_flag = 1;
 +#endif
  
        /*
         *      Main packet reception loop.  Loop receiving packets until
                 *      Check for a timeout, and run the timeout handler
                 *      if we have one.
                 */
-               if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
+               if (timeHandler && ((get_timer(timeStart)) > timeDelta)) {
                        thand_f *x;
  
  #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
                                setenv_hex("filesize", NetBootFileXferSize);
                                setenv_hex("fileaddr", load_addr);
                        }
-                       if (protocol != NETCONS)
+                       if (protocol != NETCONS) {
                                eth_halt();
-                       else
+                       } else {
                                eth_halt_state_only();
+                       }
  
                        eth_set_last_protocol(protocol);
  
        }
  
  done:
 +#ifdef CONFIG_USB_KEYBOARD
 +      net_busy_flag = 0;
 +#endif
  #ifdef CONFIG_CMD_TFTPPUT
        /* Clear out the handlers */
        net_set_udp_handler(NULL);
@@@ -1183,7 -1177,7 +1189,7 @@@ NetReceive(uchar *inpkt, int len
  #endif
  
  
 -#ifdef CONFIG_NETCONSOLE
 +#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
                nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
                                        src_ip,
                                        ntohs(ip->udp_dst),
  static int net_check_prereq(enum proto_t protocol)
  {
        switch (protocol) {
-               /* Fall through */
  #if defined(CONFIG_CMD_PING)
        case PING:
                if (NetPingIP == 0) {
@@@ -1248,6 -1241,7 +1253,7 @@@ common
  #endif
                /* Fall through */
  
+       case BOOTME:
        case NETCONS:
        case TFTPSRV:
                if (NetOurIP == 0) {
diff --combined tools/Makefile
index e549f8e63c9cbe0b1066a659efb16bd641601601,33fad6badba1f28cf1aef647ade7de8274d91ce3..06719ac817464c8e1e497b5f0908af96874f73b6
@@@ -5,6 -5,23 +5,6 @@@
  # SPDX-License-Identifier:    GPL-2.0+
  #
  
 -TOOLSUBDIRS = kernel-doc
 -
 -#
 -# Include this after HOSTOS HOSTARCH check
 -# so that we can act intelligently.
 -#
 -include $(TOPDIR)/config.mk
 -
 -#
 -# toolchains targeting win32 generate .exe files
 -#
 -ifneq (,$(findstring WIN32 ,$(shell $(HOSTCC) -E -dM -xc /dev/null)))
 -SFX = .exe
 -else
 -SFX =
 -endif
 -
  # Enable all the config-independent tools
  ifneq ($(HOST_TOOLS_ALL),)
  CONFIG_LCD_LOGO = y
@@@ -15,9 -32,6 +15,9 @@@ CONFIG_NETCONSOLE = 
  CONFIG_SHA1_CHECK_UB_IMG = y
  endif
  
 +subdir-$(HOST_TOOLS_ALL) += easylogo
 +subdir-$(HOST_TOOLS_ALL) += gdb
 +
  # Merge all the different vars for envcrc into one
  ENVCRC-$(CONFIG_ENV_IS_EMBEDDED) = y
  ENVCRC-$(CONFIG_ENV_IS_IN_DATAFLASH) = y
@@@ -29,149 -43,78 +29,149 @@@ ENVCRC-$(CONFIG_ENV_IS_IN_NVRAM) = 
  ENVCRC-$(CONFIG_ENV_IS_IN_SPI_FLASH) = y
  CONFIG_BUILD_ENVCRC ?= $(ENVCRC-y)
  
 -# Generated executable files
 -BIN_FILES-$(CONFIG_LCD_LOGO) += bmp_logo$(SFX)
 -BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo$(SFX)
 -BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
 -BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
 -BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
 -BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
 -BIN_FILES-y += mkenvimage$(SFX)
 -BIN_FILES-y += mkimage$(SFX)
 -BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
 -BIN_FILES-$(CONFIG_MX23) += mxsboot$(SFX)
 -BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
 -BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
 -BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
 -BIN_FILES-$(CONFIG_KIRKWOOD) += kwboot$(SFX)
 -BIN_FILES-y += proftool(SFX)
 -
 -# Source files which exist outside the tools directory
 -EXT_OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += common/env_embedded.o
 -EXT_OBJ_FILES-y += common/image.o
 -EXT_OBJ_FILES-$(CONFIG_FIT) += common/image-fit.o
 -EXT_OBJ_FILES-y += common/image-sig.o
 -EXT_OBJ_FILES-y += lib/crc32.o
 -EXT_OBJ_FILES-y += lib/md5.o
 -EXT_OBJ_FILES-y += lib/sha1.o
 -
 -# Source files located in the tools directory
 -OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o
 -OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
 -NOPED_OBJ_FILES-y += default_image.o
 -NOPED_OBJ_FILES-y += proftool.o
 -OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
 -NOPED_OBJ_FILES-y += fit_image.o
 -OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
 -OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
 -OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
 -NOPED_OBJ_FILES-y += aisimage.o
 -NOPED_OBJ_FILES-y += kwbimage.o
 -NOPED_OBJ_FILES-y += pblimage.o
 -NOPED_OBJ_FILES-y += imximage.o
 -NOPED_OBJ_FILES-y += image-host.o
 -NOPED_OBJ_FILES-y += omapimage.o
 -NOPED_OBJ_FILES-y += mkenvimage.o
 -NOPED_OBJ_FILES-y += mkimage.o
 -OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
 -OBJ_FILES-$(CONFIG_MX23) += mxsboot.o
 -OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
 -OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
 -NOPED_OBJ_FILES-y += os_support.o
 -OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
 -NOPED_OBJ_FILES-y += ublimage.o
 -OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o
 +hostprogs-$(CONFIG_SPL_GENERATE_ATMEL_PMECC_HEADER) += atmel_pmecc_params
  
 -# Don't build by default
 -#ifeq ($(ARCH),ppc)
 -#BIN_FILES-y += mpc86x_clk$(SFX)
 -#OBJ_FILES-y += mpc86x_clk.o
 -#endif
 +# TODO: CONFIG_CMD_LICENSE does not work
 +hostprogs-$(CONFIG_CMD_LICENSE) += bin2header
 +hostprogs-$(CONFIG_LCD_LOGO) += bmp_logo
 +hostprogs-$(CONFIG_VIDEO_LOGO) += bmp_logo
 +HOSTCFLAGS_bmp_logo.o := -pedantic
 +
 +hostprogs-$(CONFIG_BUILD_ENVCRC) += envcrc
 +envcrc-objs := envcrc.o lib/crc32.o common/env_embedded.o lib/sha1.o
 +
 +hostprogs-$(CONFIG_CMD_NET) += gen_eth_addr
 +HOSTCFLAGS_gen_eth_addr.o := -pedantic
 +
 +hostprogs-$(CONFIG_CMD_LOADS) += img2srec
 +HOSTCFLAGS_img2srec.o := -pedantic
  
- hostprogs-y += dumpimage mkimage
 +hostprogs-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes
 +HOSTCFLAGS_xway-swap-bytes.o := -pedantic
 +
 +hostprogs-y += mkenvimage
 +mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
 +
++#hostprogs-y += dumpimage mkimage
 +hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
 +
 +FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
  # Flattened device tree objects
 -LIBFDT_OBJ_FILES-y += fdt.o
 -LIBFDT_OBJ_FILES-y += fdt_ro.o
 -LIBFDT_OBJ_FILES-y += fdt_rw.o
 -LIBFDT_OBJ_FILES-y += fdt_strerror.o
 -LIBFDT_OBJ_FILES-y += fdt_wip.o
 +LIBFDT_OBJS := $(addprefix lib/libfdt/, \
 +                      fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
 +RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
 +                                      rsa-sign.o rsa-verify.o rsa-checksum.o)
 +
 +# common objs for dumpimage and mkimage
 +dumpimage-mkimage-objs := aisimage.o \
 +                      atmelimage.o \
 +                      $(FIT_SIG_OBJS-y) \
 +                      common/bootm.o \
 +                      lib/crc32.o \
 +                      default_image.o \
 +                      lib/fdtdec_common.o \
 +                      lib/fdtdec.o \
 +                      fit_common.o \
 +                      fit_image.o \
 +                      gpimage.o \
 +                      gpimage-common.o \
 +                      common/image-fit.o \
 +                      image-host.o \
 +                      common/image.o \
 +                      imagetool.o \
 +                      imximage.o \
 +                      kwbimage.o \
 +                      lib/md5.o \
 +                      mxsimage.o \
 +                      omapimage.o \
 +                      os_support.o \
 +                      pblimage.o \
 +                      pbl_crc32.o \
 +                      socfpgaimage.o \
 +                      lib/sha1.o \
 +                      lib/sha256.o \
 +                      ublimage.o \
 +                      $(LIBFDT_OBJS) \
 +                      $(RSA_OBJS-y)
 +
 +dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o
 +mkimage-objs   := $(dumpimage-mkimage-objs) mkimage.o
 +fit_info-objs   := $(dumpimage-mkimage-objs) fit_info.o
 +fit_check_sign-objs   := $(dumpimage-mkimage-objs) fit_check_sign.o
 +
 +# TODO(sjg@chromium.org): Is this correct on Mac OS?
 +
 +ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
 +# Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
 +# the mxsimage support within tools/mxsimage.c .
 +HOSTCFLAGS_mxsimage.o += -DCONFIG_MXS
 +endif
 +
 +ifdef CONFIG_FIT_SIGNATURE
 +# This affects include/image.h, but including the board config file
 +# is tricky, so manually define this options here.
 +HOST_EXTRACFLAGS      += -DCONFIG_FIT_SIGNATURE
 +endif
 +
 +# MXSImage needs LibSSL
 +ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_FIT_SIGNATURE),)
 +HOSTLOADLIBES_mkimage += -lssl -lcrypto
 +endif
 +
 +HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage)
 +HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
 +HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage)
 +
 +hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
 +hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
 +HOSTCFLAGS_mkexynosspl.o := -pedantic
  
 -# RSA objects
 -RSA_OBJ_FILES-$(CONFIG_FIT_SIGNATURE) += rsa-sign.o
 +ifdtool-objs := $(LIBFDT_OBJS) ifdtool.o
 +hostprogs-$(CONFIG_X86) += ifdtool
 +
 +hostprogs-$(CONFIG_MX23) += mxsboot
 +hostprogs-$(CONFIG_MX28) += mxsboot
 +HOSTCFLAGS_mxsboot.o := -pedantic
 +
 +hostprogs-$(CONFIG_SUNXI) += mksunxiboot
 +
 +hostprogs-$(CONFIG_NETCONSOLE) += ncb
 +hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1
 +
 +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
 +
 +# We build some files with extra pedantic flags to try to minimize things
 +# that won't build on some weird host compiler -- though there are lots of
 +# exceptions for files that aren't complaint.
 +HOSTCFLAGS_crc32.o := -pedantic
 +HOSTCFLAGS_md5.o := -pedantic
 +HOSTCFLAGS_sha1.o := -pedantic
 +HOSTCFLAGS_sha256.o := -pedantic
 +
 +# Don't build by default
 +#hostprogs-$(CONFIG_PPC) += mpc86x_clk
 +#HOSTCFLAGS_mpc86x_clk.o := -pedantic
 +
 +quiet_cmd_wrap = WRAP    $@
 +cmd_wrap = echo "\#include <../$(patsubst $(obj)/%,%,$@)>" >$@
 +
 +$(obj)/lib/%.c $(obj)/common/%.c:
 +      $(call cmd,wrap)
 +
 +clean-dirs := lib common
 +
 +always := $(hostprogs-y)
  
  # Generated LCD/video logo
 -LOGO_H = $(OBJTREE)/include/bmp_logo.h
 -LOGO_DATA_H = $(OBJTREE)/include/bmp_logo_data.h
 +LOGO_H = $(objtree)/include/bmp_logo.h
 +LOGO_DATA_H = $(objtree)/include/bmp_logo_data.h
  LOGO-$(CONFIG_LCD_LOGO) += $(LOGO_H)
  LOGO-$(CONFIG_LCD_LOGO) += $(LOGO_DATA_H)
  LOGO-$(CONFIG_VIDEO_LOGO) += $(LOGO_H)
@@@ -179,52 -122,165 +179,54 @@@ LOGO-$(CONFIG_VIDEO_LOGO) += $(LOGO_DAT
  
  # Generic logo
  ifeq ($(LOGO_BMP),)
 -LOGO_BMP= logos/denx.bmp
 +LOGO_BMP= $(srctree)/$(src)/logos/denx.bmp
  
  # Use board logo and fallback to vendor
 -ifneq ($(wildcard logos/$(BOARD).bmp),)
 -LOGO_BMP= logos/$(BOARD).bmp
 +ifneq ($(wildcard $(srctree)/$(src)/logos/$(BOARD).bmp),)
 +LOGO_BMP= $(srctree)/$(src)/logos/$(BOARD).bmp
  else
 -ifneq ($(wildcard logos/$(VENDOR).bmp),)
 -LOGO_BMP= logos/$(VENDOR).bmp
 +ifneq ($(wildcard $(srctree)/$(src)/logos/$(VENDOR).bmp),)
 +LOGO_BMP= $(srctree)/$(src)/logos/$(VENDOR).bmp
  endif
  endif
  
  endif # !LOGO_BMP
  
 -# now $(obj) is defined
 -HOSTSRCS += $(addprefix $(SRCTREE)/,$(EXT_OBJ_FILES-y:.o=.c))
 -HOSTSRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c))
 -HOSTSRCS += $(addprefix $(SRCTREE)/lib/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
 -HOSTSRCS += $(addprefix $(SRCTREE)/lib/rsa/,$(RSA_OBJ_FILES-y:.o=.c))
 -BINS  := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
 -LIBFDT_OBJS   := $(addprefix $(obj),$(LIBFDT_OBJ_FILES-y))
 -RSA_OBJS      := $(addprefix $(obj),$(RSA_OBJ_FILES-y))
 -
 -# We cannot check CONFIG_FIT_SIGNATURE here since it is not set on the host
 -FIT_SIG_OBJ_FILES     := image-sig.o
 -FIT_SIG_OBJS          := $(addprefix $(obj),$(FIT_SIG_OBJ_FILES))
 -
 -HOSTOBJS := $(addprefix $(obj),$(OBJ_FILES-y))
 -NOPEDOBJS := $(addprefix $(obj),$(NOPED_OBJ_FILES-y))
 -
  #
  # Use native tools and options
  # Define __KERNEL_STRICT_NAMES to prevent typedef overlaps
 +# Define _GNU_SOURCE to obtain the getline prototype from stdio.h
  #
 -HOSTCPPFLAGS =        -include $(SRCTREE)/include/libfdt_env.h \
 -              -idirafter $(SRCTREE)/include \
 -              -idirafter $(OBJTREE)/include2 \
 -              -idirafter $(OBJTREE)/include \
 -              -I $(SRCTREE)/lib/libfdt \
 -              -I $(SRCTREE)/tools \
 +HOST_EXTRACFLAGS += -include $(srctree)/include/libfdt_env.h \
 +              $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \
 +              -I$(srctree)/lib/libfdt \
 +              -I$(srctree)/tools \
++                -include $(srctree)/include/linux/kconfig.h \
++              -Wno-variadic-macros \
                -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \
                -DUSE_HOSTCC \
 -              -D__KERNEL_STRICT_NAMES
 -
 -
 -all:  $(obj).depend $(BINS) $(LOGO-y) subdirs
 -
 -$(obj)bin2header$(SFX): $(obj)bin2header.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)bmp_logo$(SFX): $(obj)bmp_logo.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)proftool(SFX):  $(obj)proftool.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)envcrc$(SFX):   $(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -
 -$(obj)gen_eth_addr$(SFX):     $(obj)gen_eth_addr.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)img2srec$(SFX): $(obj)img2srec.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)xway-swap-bytes$(SFX):  $(obj)xway-swap-bytes.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)mkenvimage$(SFX):       $(obj)crc32.o $(obj)mkenvimage.o \
 -      $(obj)os_support.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)mkimage$(SFX):  $(obj)aisimage.o \
 -                      $(obj)crc32.o \
 -                      $(obj)default_image.o \
 -                      $(obj)fit_image.o \
 -                      $(obj)image-fit.o \
 -                      $(obj)image.o \
 -                      $(obj)image-host.o \
 -                      $(FIT_SIG_OBJS) \
 -                      $(obj)imximage.o \
 -                      $(obj)kwbimage.o \
 -                      $(obj)pblimage.o \
 -                      $(obj)md5.o \
 -                      $(obj)mkimage.o \
 -                      $(obj)os_support.o \
 -                      $(obj)omapimage.o \
 -                      $(obj)sha1.o \
 -                      $(obj)ublimage.o \
 -                      $(LIBFDT_OBJS) \
 -                      $(RSA_OBJS)
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
 -      $(HOSTSTRIP) $@
 -
 -$(obj)mk$(BOARD)spl$(SFX):    $(obj)mkexynosspl.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)mpc86x_clk$(SFX):       $(obj)mpc86x_clk.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)mxsboot$(SFX):  $(obj)mxsboot.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 -
 -$(obj)ncb$(SFX):      $(obj)ncb.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 +              -D__KERNEL_STRICT_NAMES \
 +              -D_GNU_SOURCE
  
 -$(obj)ubsha1$(SFX):   $(obj)os_support.o $(obj)sha1.o $(obj)ubsha1.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 +__build:      $(LOGO-y)
  
 -$(obj)kwboot$(SFX): $(obj)kwboot.o
 -      $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 -      $(HOSTSTRIP) $@
 +$(LOGO_H):    $(obj)/bmp_logo $(LOGO_BMP)
 +      $(obj)/bmp_logo --gen-info $(LOGO_BMP) > $@
  
 -# Some of the tool objects need to be accessed from outside the tools directory
 -$(obj)%.o: $(SRCTREE)/common/%.c
 -      $(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
 +$(LOGO_DATA_H):       $(obj)/bmp_logo $(LOGO_BMP)
 +      $(obj)/bmp_logo --gen-data $(LOGO_BMP) > $@
  
 -$(obj)%.o: $(SRCTREE)/lib/%.c
 -      $(HOSTCC) -g $(HOSTCFLAGS) -c -o $@ $<
 +# Let clean descend into subdirs
 +subdir- += env
  
 -$(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
 -      $(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
 +ifneq ($(CROSS_BUILD_TOOLS),)
 +HOSTCC = $(CC)
  
 -$(obj)%.o: $(SRCTREE)/lib/rsa/%.c
 -      $(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
 +quiet_cmd_crosstools_strip = STRIP   $^
 +      cmd_crosstools_strip = $(STRIP) $^; touch $@
 +$(obj)/.strip: $(call objectify,$(filter $(always),$(hostprogs-y)))
 +      $(call cmd,crosstools_strip)
  
 -subdirs:
 -ifeq ($(TOOLSUBDIRS),)
 -      @:
 -else
 -      @for dir in $(TOOLSUBDIRS) ; do \
 -          $(MAKE) \
 -              HOSTOS=$(HOSTOS) \
 -              HOSTARCH=$(HOSTARCH) \
 -              -C $$dir || exit 1 ; \
 -      done
 +always += .strip
  endif
 -
 -$(LOGO_H):    $(obj)bmp_logo $(LOGO_BMP)
 -      $(obj)./bmp_logo --gen-info $(LOGO_BMP) > $@
 -
 -$(LOGO_DATA_H):       $(obj)bmp_logo $(LOGO_BMP)
 -      $(obj)./bmp_logo --gen-data $(LOGO_BMP) > $@
 -
 -#########################################################################
 -
 -# defines $(obj).depend target
 -include $(SRCTREE)/rules.mk
 -
 -sinclude $(obj).depend
 -
 -#########################################################################
 +clean-files += .strip