]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
update to 2015.04-rc1
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 9 Mar 2015 08:21:53 +0000 (09:21 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 9 Mar 2015 08:21:53 +0000 (09:21 +0100)
31 files changed:
1  2 
Kconfig
README
arch/arm/Kconfig
arch/arm/cpu/arm926ejs/cpu.c
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/omap-common/boot-common.c
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/emif.h
arch/arm/lib/cache.c
board/karo/tx53/u-boot.lds
common/Kconfig
common/Makefile
common/cmd_mmc.c
common/lcd.c
common/spl/spl.c
drivers/gpio/gpio-uclass.c
drivers/i2c/Kconfig
drivers/mmc/Kconfig
drivers/mmc/mmc.c
drivers/mmc/omap_hsmmc.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/omap_gpmc.c
drivers/net/phy/phy.c
include/asm-generic/gpio.h
include/configs/tx53.h
include/lcd.h
include/net.h
include/netdev.h
net/Makefile
tools/Makefile

diff --combined Kconfig
index 3e74c891b0928540f2b1dfc69e7a64b9c1237c87,fed488fdaf94212dfce21902d2cf812a827f819e..861622664fcba27cfbf4445128ce44c8db4b9cb2
+++ b/Kconfig
@@@ -70,7 -70,8 +70,7 @@@ menu "Boot images
  
  config SPL_BUILD
        bool
 -      depends on $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
 -      default y
 +      default y if $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
  
  config TPL_BUILD
        bool
@@@ -115,8 -116,9 +115,9 @@@ config FIT_VERBOS
        depends on FIT
  
  config FIT_SIGNATURE
-       bool "Enabel signature verification of FIT uImages"
+       bool "Enable signature verification of FIT uImages"
        depends on FIT
+       select RSA
        help
          This option enables signature verification of FIT uImages,
          using a hash signed and verified using RSA.
@@@ -142,12 -144,18 +143,20 @@@ config SYS_TEXT_BAS
        help
          TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
  
+ config SYS_CLK_FREQ
+       depends on ARC
+       int "CPU clock frequency"
+       help
+         TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture
  endmenu               # Boot images
  
  source "arch/Kconfig"
  
  source "common/Kconfig"
  
++source "disk/Kconfig"
++
  source "dts/Kconfig"
  
  source "net/Kconfig"
diff --combined README
index 4f8842d2926e9a75b2c513103041aeb07095f3a0,a28ff133ee057c17af79a397e44325328f82dedf..a435c8b2fa7ce054530002b7d5d8f20f197710ad
--- 1/README
--- 2/README
+++ b/README
@@@ -182,7 -182,6 +182,6 @@@ Directory Hierarchy
      /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
@@@ -2208,17 -2207,6 +2207,17 @@@ CBFS (Coreboot Filesystem) suppor
                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:
                This enables the RSA algorithm used for FIT image verification
                in U-Boot. See doc/uImage.FIT/signature.txt for more information.
  
+               The Modular Exponentiation algorithm in RSA is implemented using
+               driver model. So CONFIG_DM needs to be enabled by default for this
+               library to function.
                The signing part is build into mkimage regardless of this
-               option.
+               option. The software based modular exponentiation is built into
+               mkimage irrespective of this option.
  
  - bootcount support:
                CONFIG_BOOTCOUNT_LIMIT
@@@ -5911,9 -5904,10 +5915,10 @@@ option performs the converse operation 
  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'
+       tools/dumpimage -i image -T type -p position data_file
+         -i ==> extract from the 'image' a specific 'data_file'
+         -T ==> set image type to 'type'
+         -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'
  
  
  Installing a Linux Image:
diff --combined arch/arm/Kconfig
index 682f882fc0610f89c57b97f38221aa3478e0056f,986b4c5d81db1009110eafb2c4606c79675c03a7..0219f4ec6010a02f5d3d508e01f8e9710a23ad43
@@@ -51,6 -51,13 +51,13 @@@ config SYS_CP
          default "sa1100" if CPU_SA1100
        default "armv8" if ARM64
  
+ config SEMIHOSTING
+       bool "support boot from semihosting"
+       help
+         In emulated environments, semihosting is a way for
+         the hosted environment to call out to the emulator to
+         retrieve files from the host machine.
  choice
        prompt "Target select"
  
@@@ -251,28 -258,6 +258,28 @@@ config TARGET_TX2
        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
@@@ -742,10 -727,19 +749,19 @@@ config TEGR
        select CPU_ARM720T if SPL_BUILD
        select CPU_V7 if !SPL_BUILD
  
- config TARGET_VEXPRESS_AEMV8A
+ config TARGET_VEXPRESS64_AEMV8A
        bool "Support vexpress_aemv8a"
        select ARM64
  
+ config TARGET_VEXPRESS64_BASE_FVP
+       bool "Support Versatile Express ARMv8a FVP BASE model"
+       select ARM64
+       select SEMIHOSTING
+ config TARGET_VEXPRESS64_JUNO
+       bool "Support Versatile Express Juno Development Platform"
+       select ARM64
  config TARGET_LS2085A_EMU
        bool "Support ls2085a_emu"
        select ARM64
@@@ -949,11 -943,6 +965,11 @@@ 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"
index 174c8d36b21134f1688ad4efdadad4de910a512b,a90ce3047bd27f2f100512ce6239073ac6c92fa9..d1d2a176f673448321a9edb5869d166b3fb54d85
@@@ -15,7 -15,6 +15,7 @@@
  
  #include <common.h>
  #include <command.h>
 +#include <lcd.h>
  #include <asm/system.h>
  
  static void cache_flush(void);
@@@ -31,14 -30,6 +31,14 @@@ int cleanup_before_linux (void
  
        disable_interrupts ();
  
 +#ifdef CONFIG_LCD
 +      {
 +              /* switch off LCD panel */
 +              lcd_panel_disable();
 +              /* disable LCD controller */
 +              lcd_disable();
 +      }
 +#endif
  
        /* turn off I/D-cache */
        icache_disable();
@@@ -54,7 -45,9 +54,9 @@@
  /* flush I/D-cache */
  static void cache_flush (void)
  {
+ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
        unsigned long i = 0;
  
        asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
+ #endif
  }
index f5a420378e462f0dd08ede337ea5fedb765d77ad,81477aa7b0c3fc9e432a248ca632fc0672a693db..64322b828a0c515187e93eada473481ee612cf1e
@@@ -111,7 -111,7 +111,7 @@@ const struct gpio_bank *const omap_gpio
  #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
  
  /* AM33XX has two MUSB controllers which can be host or gadget */
@@@ -286,14 -284,6 +286,6 @@@ void s_init(void
         */
  #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();
        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 */
diff --combined arch/arm/cpu/armv7/cpu.c
index a5794c6cdba303e097dee7872a3c28fb2d20274b,c56417dd2f1ec81d8fa1088d8c12fc0aaf6c3848..f381d2ff9872f13464f16e5e3eb414150ab2cc61
@@@ -17,7 -17,6 +17,7 @@@
  
  #include <common.h>
  #include <command.h>
 +#include <lcd.h>
  #include <asm/system.h>
  #include <asm/cache.h>
  #include <asm/armv7.h>
@@@ -35,15 -34,7 +35,15 @@@ int cleanup_before_linux(void
         */
  #ifndef CONFIG_SPL_BUILD
        disable_interrupts();
 -#endif
 +#ifdef CONFIG_LCD
 +      {
 +              /* switch off LCD panel */
 +              lcd_panel_disable();
 +              /* disable LCD controller */
 +              lcd_disable();
 +      }
 +#endif /* CONFIG_LCD */
 +#endif /* CONFIG_SPL_BUILD */
  
        /*
         * Turn off I-cache and invalidate it
@@@ -62,7 -53,7 +62,7 @@@
         * After D-cache is flushed and before it is disabled there may
         * be some new valid entries brought into the cache. We are sure
         * that these lines are not dirty and will not affect our execution.
-        * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+        * (because unwinding the call-stack and setting a bit in CP15 SCTLR
         * is all we did during this. We have not pushed anything on to the
         * stack. Neither have we affected any static data)
         * So just invalidate the entire d-cache again to avoid coherency
index fdef7a708fb6c44f13336c79093bf8aa90dc4ef0,17500f2315ee9d3d5a8a5868c3e3e75f46a7148b..ab4a070f97007bf5d308ad8cc19395ea8282c9ef
@@@ -85,7 -85,7 +85,7 @@@ void save_omap_boot_params(void
  #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)
  
  void spl_board_init(void)
  {
+       /*
+        * Save the boot parameters passed from romcode.
+        * We cannot delay the saving further than this,
+        * to prevent overwrites.
+        */
+       save_omap_boot_params();
+       /* Prepare console output */
+       preloader_console_init();
  #ifdef CONFIG_SPL_NAND_SUPPORT
        gpmc_init();
  #endif
index 9367a707d3f0c966136ded10129908b60097ad7d,b94b56cba73d3d8ef5f569eb9c126f40d2033fdc..3f1da852e55c687e55b2d352e8963e1a3956b49c
  
  #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 */
@@@ -60,8 -60,8 +60,8 @@@
  #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))
  
  #define PRM_RSTCTRL_RESET             0x01
  #define PRM_RSTST_WARM_RESET_MASK     0x232
@@@ -106,9 -106,7 +106,9 @@@ struct cm_wkuppll 
        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 */
@@@ -152,7 -150,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 */
@@@ -221,6 -219,12 +221,12 @@@ struct cm_dpll 
        unsigned int resv4[2];
        unsigned int clklcdcpixelclk;   /* offset 0x34 */
  };
+ struct prm_device_inst {
+       unsigned int prm_rstctrl;
+       unsigned int prm_rsttime;
+       unsigned int prm_rstst;
+ };
  #else
  /* Encapsulating core pll registers */
  struct cm_wkuppll {
@@@ -388,6 -392,11 +394,11 @@@ struct cm_device_inst 
        unsigned int cm_dll_ctrl;
  };
  
+ struct prm_device_inst {
+       unsigned int prm_rstctrl;
+       unsigned int prm_rstst;
+ };
  struct cm_dpll {
        unsigned int resv1;
        unsigned int clktimer2clk;      /* offset 0x04 */
@@@ -445,7 -454,7 +456,7 @@@ 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 */
  };
  
@@@ -466,7 -475,7 +477,7 @@@ 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;
  };
@@@ -576,22 -585,7 +587,22 @@@ struct pwmss_ecap_regs 
  #define ECTRL2_PLSL_LOW               BIT(10)
  #define ECTRL2_SYNC_EN                BIT(5)
  
 +#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 cd4fc9075cd87e6d673ef3ad663c52145b32343c,342f045f41419471adea238aed0fcb309e7185d2..72b6733c9a3aa68e62784632bcfff2d0bf03ced8
  
  /* 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[28];
 -      u32 padding10[20];
 -      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 emif_ddr_ext_phy_ctrl_25;
 -      u32 emif_ddr_ext_phy_ctrl_25_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_26;
 -      u32 emif_ddr_ext_phy_ctrl_26_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_27;
 -      u32 emif_ddr_ext_phy_ctrl_27_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_28;
 -      u32 emif_ddr_ext_phy_ctrl_28_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_29;
 -      u32 emif_ddr_ext_phy_ctrl_29_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_30;
 -      u32 emif_ddr_ext_phy_ctrl_30_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_31;
 -      u32 emif_ddr_ext_phy_ctrl_31_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_32;
 -      u32 emif_ddr_ext_phy_ctrl_32_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_33;
 -      u32 emif_ddr_ext_phy_ctrl_33_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_34;
 -      u32 emif_ddr_ext_phy_ctrl_34_shdw;
 -      u32 emif_ddr_ext_phy_ctrl_35;
 -      u32 emif_ddr_ext_phy_ctrl_35_shdw;
 +      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[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 padding9[6];                        /* 0x124 */
-       u32 emif_ddr_phy_status[21];            /* 0x13c */
-       u32 padding10[27];                      /* 0x1fc */
++      u32 emif_cos_config;                    /* 0x124 */
++      u32 padding9[6];                        /* 0x128 */
++      u32 emif_ddr_phy_status[28];            /* 0x140 */
++      u32 padding10[20];                      /* 0x1b0 */
 +      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 */
++      u32 emif_ddr_ext_phy_ctrl_25;           /* 0x2b0 */
++      u32 emif_ddr_ext_phy_ctrl_25_shdw;      /* 0x2b4 */
++      u32 emif_ddr_ext_phy_ctrl_26;           /* 0x2b8 */
++      u32 emif_ddr_ext_phy_ctrl_26_shdw;      /* 0x2bc */
++      u32 emif_ddr_ext_phy_ctrl_27;           /* 0x2c0 */
++      u32 emif_ddr_ext_phy_ctrl_27_shdw;      /* 0x2c4 */
++      u32 emif_ddr_ext_phy_ctrl_28;           /* 0x2c8 */
++      u32 emif_ddr_ext_phy_ctrl_28_shdw;      /* 0x2cc */
++      u32 emif_ddr_ext_phy_ctrl_29;           /* 0x2d0 */
++      u32 emif_ddr_ext_phy_ctrl_29_shdw;      /* 0x2d4 */
++      u32 emif_ddr_ext_phy_ctrl_30;           /* 0x2d8 */
++      u32 emif_ddr_ext_phy_ctrl_30_shdw;      /* 0x2dc */
++      u32 emif_ddr_ext_phy_ctrl_31;           /* 0x2e0 */
++      u32 emif_ddr_ext_phy_ctrl_31_shdw;      /* 0x2e4 */
++      u32 emif_ddr_ext_phy_ctrl_32;           /* 0x2e8 */
++      u32 emif_ddr_ext_phy_ctrl_32_shdw;      /* 0x2ec */
++      u32 emif_ddr_ext_phy_ctrl_33;           /* 0x2f0 */
++      u32 emif_ddr_ext_phy_ctrl_33_shdw;      /* 0x2f4 */
++      u32 emif_ddr_ext_phy_ctrl_34;           /* 0x2f8 */
++      u32 emif_ddr_ext_phy_ctrl_34_shdw;      /* 0x2fc */
++      u32 emif_ddr_ext_phy_ctrl_35;           /* 0x300 */
++      u32 emif_ddr_ext_phy_ctrl_35_shdw;      /* 0x304 */
+       union {
 -              u32 emif_ddr_ext_phy_ctrl_36;
++              u32 emif_ddr_ext_phy_ctrl_36;   /* 0x308 */
+               u32 emif_ddr_fifo_misaligned_clear_1;
+       };
+       union {
 -              u32 emif_ddr_ext_phy_ctrl_36_shdw;
++              u32 emif_ddr_ext_phy_ctrl_36_shdw; /* 0x30c */
+               u32 emif_ddr_fifo_misaligned_clear_2;
+       };
  };
  
  struct dmm_lisa_map_regs {
@@@ -1181,9 -1209,9 +1209,9 @@@ static inline u32 emif_sdram_type(void
  
  /* 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
diff --combined arch/arm/lib/cache.c
index c89e0f40c3f1985d0a5df3948428b024f6ca0c75,74cfde637c1c433f3f834cdfbdac48b05ff78b6a..20c708a7c3edfe7239aa673205e61c65602031e8
@@@ -24,14 -24,14 +24,16 @@@ __weak void flush_cache(unsigned long s
  
  #endif /* CONFIG_CPU_ARM1136 */
  
- #ifdef CONFIG_ARM926EJS
+ #ifdef CONFIG_CPU_ARM926EJS
+ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 -      /* 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));
 +      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
+ #endif /* CONFIG_CPU_ARM926EJS */
        return;
  }
  
index 9276d3b130c121296edfcd0b55aa192bdc0dcbd9,0000000000000000000000000000000000000000..9de3dc5182e4501168002430cd86adb76839fa20
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,142 @@@
-               KEEP(board/karo/tx53/lowlevel_init.o (.text*))
 +/*
 + * (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 :
 +      {
-       _end = .;
 +              *(.__image_copy_start)
++              *(.vectors)
 +              CPUDIR/start.o (.text*)
++              . = 0x400;
++              KEEP(BOARDDIR/lowlevel_init.o (.text*))
 +              *(.text*)
 +      }
 +
++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI)
++
++#ifndef CONFIG_ARMV7_SECURE_BASE
++#define CONFIG_ARMV7_SECURE_BASE
++#endif
++
++      .__secure_start : {
++              . = ALIGN(0x1000);
++              *(.__secure_start)
++      }
++
++      .secure_text CONFIG_ARMV7_SECURE_BASE :
++              AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
++      {
++              *(._secure.text)
++      }
++
++      . = LOADADDR(.__secure_start) +
++              SIZEOF(.__secure_start) +
++              SIZEOF(.secure_text);
++
++      __secure_end_lma = .;
++      .__secure_end : AT(__secure_end_lma) {
++              *(.__secure_end)
++              LONG(0x1d1071c);        /* Must output something to reset LMA */
++      }
++#endif
++
 +      . = 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)
 +      }
 +
 +      /* Workaround for an apparent bug in i.MX53 ROM Code,
 +       * that skips loading the last block if it doesn't
 +       * end on a 4KiB boundary.
 +       */
++
 +      . = ALIGN(4096);
 +      .uboot_img_end :
 +      {
 +              *(.__uboot_img_end)
 +      }
 +
-  
-       /DISCARD/ : { *(.bss*) }
-       /DISCARD/ : { *(.dynstr*) }
-       /DISCARD/ : { *(.dynsym*) }
-       /DISCARD/ : { *(.dynamic*) }
-       /DISCARD/ : { *(.hash*) }
-       /DISCARD/ : { *(.plt*) }
-       /DISCARD/ : { *(.interp*) }
-       /DISCARD/ : { *(.gnu*) }
++      _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.*) }
 +}
diff --combined common/Kconfig
index 72f7a07e96e069dc41b4bdbce94b51b963a8cca8,fd84fa08bd3efc2569ac4200684f26abca5ac205..d4130ceb069908c965e57faf27bae09f754b59a2
@@@ -53,17 -53,6 +53,17 @@@ config CMD_BOOT
        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
@@@ -92,17 -81,6 +92,17 @@@ config CMD_XIM
  
  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
@@@ -129,26 -107,6 +129,26 @@@ config CMD_SAVEEN
  
  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
@@@ -213,32 -171,11 +213,33 @@@ config CMD_FLAS
            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"
++      select PARTITIONS
 +      help
 +        MMC/SD support.
 +
  config CMD_SPI
        bool "sspi"
        help
@@@ -349,11 -286,6 +350,11 @@@ endmen
  
  menu "Misc commands"
  
 +config CMD_CACHE
 +      bool "cache control"
 +      help
 +        Enable commands to switch data cache on/off.
 +
  config CMD_TIME
        bool "time"
        help
diff --combined common/Makefile
index ca9a4b0dfc8780078fc8753c5a684144d8082652,9579ab4c982287f6913beeff41b92b3a85731cae..fcdb749fd6d94fff031cadbfffc1ccb1e51779e3
@@@ -27,6 -27,8 +27,8 @@@ endi
  # boards
  obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
  obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
+ obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+ obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
  
  # core command
  obj-y += cmd_boot.o
@@@ -63,7 -65,6 +65,7 @@@ obj-$(CONFIG_CMD_SOURCE) += cmd_source.
  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
@@@ -197,7 -198,7 +199,7 @@@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_s
  obj-$(CONFIG_I2C_EDID) += edid.o
  obj-$(CONFIG_KALLSYMS) += kallsyms.o
  obj-y += splash.o
- obj-$(CONFIG_LCD) += lcd.o
+ obj-$(CONFIG_LCD) += lcd.o lcd_console.o
  obj-$(CONFIG_LYNXKDI) += lynxkdi.o
  obj-$(CONFIG_MENU) += menu.o
  obj-$(CONFIG_MODEM_SUPPORT) += modem.o
diff --combined common/cmd_mmc.c
index 4565a216682e4a02273654615bbbd81e22ddbd82,4e28c9d7a4d6541f0c1633ee494b77e476b5e776..c89782ab4bd4bc8abf95d823b4e02a787a2f7cb7
@@@ -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(
@@@ -73,6 -73,8 +73,8 @@@
  
  static void print_mmcinfo(struct mmc *mmc)
  {
+       int i;
        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("Bus Width: %d-bit%s\n", mmc->bus_width,
                        mmc->ddr_mode ? " DDR" : "");
+       puts("Erase Group Size: ");
+       print_size(((u64)mmc->erase_grp_size) << 9, "\n");
+       if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
+               bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
+               bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
+               puts("HC WP Group Size: ");
+               print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
+               puts("User Capacity: ");
+               print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
+               if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR)
+                       puts(" WRREL\n");
+               else
+                       putc('\n');
+               if (usr_enh) {
+                       puts("User Enhanced Start: ");
+                       print_size(mmc->enh_user_start, "\n");
+                       puts("User Enhanced Size: ");
+                       print_size(mmc->enh_user_size, "\n");
+               }
+               puts("Boot Capacity: ");
+               print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n");
+               puts("RPMB Capacity: ");
+               print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n");
+               for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
+                       bool is_enh = has_enh &&
+                               (mmc->part_attr & EXT_CSD_ENH_GP(i));
+                       if (mmc->capacity_gp[i]) {
+                               printf("GP%i Capacity: ", i+1);
+                               print_size(mmc->capacity_gp[i],
+                                          is_enh ? " ENH" : "");
+                               if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i))
+                                       puts(" WRREL\n");
+                               else
+                                       putc('\n');
+                       }
+               }
+       }
  }
  static struct mmc *init_mmc_device(int dev, bool force_init)
  {
@@@ -116,7 -160,7 +160,7 @@@ static int do_mmcinfo(cmd_tbl_t *cmdtp
                        curr_device = 0;
                else {
                        puts("No MMC device available\n");
 -                      return 1;
 +                      return CMD_RET_FAILURE;
                }
        }
  
@@@ -444,6 -488,157 +488,157 @@@ static int do_mmc_list(cmd_tbl_t *cmdtp
        print_mmc_devices('\n');
        return CMD_RET_SUCCESS;
  }
+ static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
+                            int argc, char * const argv[])
+ {
+       int i = 0;
+       memset(&pconf->user, 0, sizeof(pconf->user));
+       while (i < argc) {
+               if (!strcmp(argv[i], "enh")) {
+                       if (i + 2 >= argc)
+                               return -1;
+                       pconf->user.enh_start =
+                               simple_strtoul(argv[i+1], NULL, 10);
+                       pconf->user.enh_size =
+                               simple_strtoul(argv[i+2], NULL, 10);
+                       i += 3;
+               } else if (!strcmp(argv[i], "wrrel")) {
+                       if (i + 1 >= argc)
+                               return -1;
+                       pconf->user.wr_rel_change = 1;
+                       if (!strcmp(argv[i+1], "on"))
+                               pconf->user.wr_rel_set = 1;
+                       else if (!strcmp(argv[i+1], "off"))
+                               pconf->user.wr_rel_set = 0;
+                       else
+                               return -1;
+                       i += 2;
+               } else {
+                       break;
+               }
+       }
+       return i;
+ }
+ static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
+                          int argc, char * const argv[])
+ {
+       int i;
+       memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
+       if (1 >= argc)
+               return -1;
+       pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10);
+       i = 1;
+       while (i < argc) {
+               if (!strcmp(argv[i], "enh")) {
+                       pconf->gp_part[pidx].enhanced = 1;
+                       i += 1;
+               } else if (!strcmp(argv[i], "wrrel")) {
+                       if (i + 1 >= argc)
+                               return -1;
+                       pconf->gp_part[pidx].wr_rel_change = 1;
+                       if (!strcmp(argv[i+1], "on"))
+                               pconf->gp_part[pidx].wr_rel_set = 1;
+                       else if (!strcmp(argv[i+1], "off"))
+                               pconf->gp_part[pidx].wr_rel_set = 0;
+                       else
+                               return -1;
+                       i += 2;
+               } else {
+                       break;
+               }
+       }
+       return i;
+ }
+ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
+                             int argc, char * const argv[])
+ {
+       struct mmc *mmc;
+       struct mmc_hwpart_conf pconf = { };
+       enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
+       int i, r, pidx;
+       mmc = init_mmc_device(curr_device, false);
+       if (!mmc)
+               return CMD_RET_FAILURE;
+       if (argc < 1)
+               return CMD_RET_USAGE;
+       i = 1;
+       while (i < argc) {
+               if (!strcmp(argv[i], "user")) {
+                       i++;
+                       r = parse_hwpart_user(&pconf, argc-i, &argv[i]);
+                       if (r < 0)
+                               return CMD_RET_USAGE;
+                       i += r;
+               } else if (!strncmp(argv[i], "gp", 2) &&
+                          strlen(argv[i]) == 3 &&
+                          argv[i][2] >= '1' && argv[i][2] <= '4') {
+                       pidx = argv[i][2] - '1';
+                       i++;
+                       r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
+                       if (r < 0)
+                               return CMD_RET_USAGE;
+                       i += r;
+               } else if (!strcmp(argv[i], "check")) {
+                       mode = MMC_HWPART_CONF_CHECK;
+                       i++;
+               } else if (!strcmp(argv[i], "set")) {
+                       mode = MMC_HWPART_CONF_SET;
+                       i++;
+               } else if (!strcmp(argv[i], "complete")) {
+                       mode = MMC_HWPART_CONF_COMPLETE;
+                       i++;
+               } else {
+                       return CMD_RET_USAGE;
+               }
+       }
+       puts("Partition configuration:\n");
+       if (pconf.user.enh_size) {
+               puts("\tUser Enhanced Start: ");
+               print_size(((u64)pconf.user.enh_start) << 9, "\n");
+               puts("\tUser Enhanced Size: ");
+               print_size(((u64)pconf.user.enh_size) << 9, "\n");
+       } else {
+               puts("\tNo enhanced user data area\n");
+       }
+       if (pconf.user.wr_rel_change)
+               printf("\tUser partition write reliability: %s\n",
+                      pconf.user.wr_rel_set ? "on" : "off");
+       for (pidx = 0; pidx < 4; pidx++) {
+               if (pconf.gp_part[pidx].size) {
+                       printf("\tGP%i Capacity: ", pidx+1);
+                       print_size(((u64)pconf.gp_part[pidx].size) << 9,
+                                  pconf.gp_part[pidx].enhanced ?
+                                  " ENH\n" : "\n");
+               } else {
+                       printf("\tNo GP%i partition\n", pidx+1);
+               }
+               if (pconf.gp_part[pidx].wr_rel_change)
+                       printf("\tGP%i write reliability: %s\n", pidx+1,
+                              pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
+       }
+       if (!mmc_hwpart_config(mmc, &pconf, mode)) {
+               if (mode == MMC_HWPART_CONF_COMPLETE)
+                       puts("Partitioning successful, "
+                            "power-cycle to make effective\n");
+               return CMD_RET_SUCCESS;
+       } else {
+               puts("Failed!\n");
+               return CMD_RET_FAILURE;
+       }
+ }
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
  static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
                          int argc, char * const argv[])
@@@ -601,6 -796,7 +796,7 @@@ static cmd_tbl_t cmd_mmc[] = 
        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, "", ""),
+       U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
  #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, "", ""),
@@@ -640,7 -836,7 +836,7 @@@ static int do_mmcops(cmd_tbl_t *cmdtp, 
  }
  
  U_BOOT_CMD(
-       mmc, 7, 1, do_mmcops,
+       mmc, 29, 1, do_mmcops,
        "MMC sub system",
        "info - display info of the current MMC device\n"
        "mmc read addr blk# cnt\n"
        "mmc part - lists available partition on current mmc device\n"
        "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
        "mmc list - lists available devices\n"
+       "mmc hwpartition [args...] - does hardware partitioning\n"
+       "  arguments (sizes in 512-byte blocks):\n"
+       "    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n"
+       "    [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n"
+       "    [check|set|complete] - mode, complete set partitioning completed\n"
+       "  WARNING: Partitioning is a write-once setting once it is set to complete.\n"
+       "  Power cycling is required to initialize partitions after set to complete.\n"
  #ifdef CONFIG_SUPPORT_EMMC_BOOT
        "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
        " - Set the BOOT_BUS_WIDTH field of the specified device\n"
diff --combined common/lcd.c
index 5ac4fd697c73a95bc82ad014c2a26af8cb5802a0,1195a54efcc742837f3cb703b4c8ad6f5d356569..41af1b199b3ba3955a8b6897463ace2e66c3bb02
@@@ -60,7 -60,7 +60,7 @@@
  #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
  #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
  #endif
  
- /* By default we scroll by a single line */
- #ifndef CONFIG_CONSOLE_SCROLL_LINES
- #define CONFIG_CONSOLE_SCROLL_LINES 1
- #endif
- /************************************************************************/
- /* ** CONSOLE DEFINITIONS & FUNCTIONS                                 */
- /************************************************************************/
- #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- # define CONSOLE_ROWS         ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
-                                       / VIDEO_FONT_HEIGHT)
- #else
- # define CONSOLE_ROWS         (panel_info.vl_row / VIDEO_FONT_HEIGHT)
- #endif
- #define CONSOLE_COLS          (panel_info.vl_col / VIDEO_FONT_WIDTH)
- #define CONSOLE_ROW_SIZE      (VIDEO_FONT_HEIGHT * lcd_line_length)
- #define CONSOLE_ROW_FIRST     lcd_console_address
- #define CONSOLE_ROW_SECOND    (lcd_console_address + CONSOLE_ROW_SIZE)
- #define CONSOLE_ROW_LAST      (lcd_console_address + CONSOLE_SIZE \
-                                       - CONSOLE_ROW_SIZE)
- #define CONSOLE_SIZE          (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
- #define CONSOLE_SCROLL_SIZE   (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
- #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_COLOR32)
- # define COLOR_MASK(c)                (c)
- #else
+ #if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \
+       (LCD_BPP != LCD_COLOR32)
  # error Unsupported LCD BPP.
  #endif
  
  DECLARE_GLOBAL_DATA_PTR;
  
- static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
- static inline void lcd_putc_xy(ushort x, ushort y, uchar  c);
  static int lcd_init(void *lcdbase);
  
  static void *lcd_logo(void);
@@@ -125,10 -93,6 +93,6 @@@ int lcd_line_length
  
  char lcd_is_enabled = 0;
  
- static short console_col;
- static short console_row;
- static void *lcd_console_address;
  static void *lcd_base;                        /* Start of framebuffer memory  */
  
  static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
@@@ -166,205 -130,16 +130,16 @@@ void lcd_set_flush_dcache(int flush
  
  /*----------------------------------------------------------------------*/
  
- static void console_scrollup(void)
- {
-       const int rows = CONFIG_CONSOLE_SCROLL_LINES;
-       /* Copy up rows ignoring those that will be overwritten */
-       memcpy(CONSOLE_ROW_FIRST,
-              lcd_console_address + CONSOLE_ROW_SIZE * rows,
-              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;
- }
- /*----------------------------------------------------------------------*/
- static inline void console_back(void)
- {
-       if (--console_col < 0) {
-               console_col = CONSOLE_COLS-1 ;
-               if (--console_row < 0)
-                       console_row = 0;
-       }
-       lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
-               console_row * VIDEO_FONT_HEIGHT, ' ');
- }
- /*----------------------------------------------------------------------*/
- static inline void console_newline(void)
- {
-       console_col = 0;
-       /* Check if we need to scroll the terminal */
-       if (++console_row >= CONSOLE_ROWS)
-               console_scrollup();
-       else
-               lcd_sync();
- }
- /*----------------------------------------------------------------------*/
  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) {
-               serial_putc(c);
-               return;
-       }
-       switch (c) {
-       case '\r':
-               console_col = 0;
-               return;
-       case '\n':
-               console_newline();
-               return;
-       case '\t':      /* Tab (8 chars alignment) */
-               console_col +=  8;
-               console_col &= ~7;
-               if (console_col >= CONSOLE_COLS)
-                       console_newline();
-               return;
-       case '\b':
-               console_back();
-               return;
-       default:
-               lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
-                       console_row * VIDEO_FONT_HEIGHT, c);
-               if (++console_col >= CONSOLE_COLS)
-                       console_newline();
-       }
- }
- /*----------------------------------------------------------------------*/
  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) {
-               serial_puts(s);
-               return;
-       }
-       while (*s)
-               lcd_putc(*s++);
-       lcd_sync();
- }
- /*----------------------------------------------------------------------*/
- void lcd_printf(const char *fmt, ...)
- {
-       va_list args;
-       char buf[CONFIG_SYS_PBSIZE];
-       va_start(args, fmt);
-       vsprintf(buf, fmt, args);
-       va_end(args);
-       lcd_puts(buf);
- }
- /************************************************************************/
- /* ** Low-Level Graphics Routines                                     */
- /************************************************************************/
- static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
- {
-       void *dest;
-       ushort row;
- #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
-       y += BMP_LOGO_HEIGHT;
- #endif
- #if LCD_BPP == LCD_MONOCHROME
-       ushort off  = x * NBITS(LCD_BPP) % 8;
- #endif
-       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_COLOR16
-               ushort *d = (ushort *)dest;
- #elif LCD_BPP == LCD_COLOR32
-               u32 *d = (u32 *)dest;
- #else
-               uchar *d = dest;
- #endif
- #if LCD_BPP == LCD_MONOCHROME
-               uchar rest = *d & -(1 << (8 - off));
-               uchar sym;
- #endif
-               for (i = 0; i < count; ++i) {
-                       uchar c, bits;
-                       c = *s++;
-                       bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
- #if LCD_BPP == LCD_MONOCHROME
-                       sym  = (COLOR_MASK(lcd_color_fg) & bits) |
-                               (COLOR_MASK(lcd_color_bg) & ~bits);
-                       *d++ = rest | (sym >> off);
-                       rest = sym << (8-off);
- #else
-                       for (c = 0; c < 8; ++c) {
-                               *d++ = (bits & 0x80) ?
-                                               lcd_color_fg : lcd_color_bg;
-                               bits <<= 1;
-                       }
- #endif
-               }
- #if LCD_BPP == LCD_MONOCHROME
-               *d  = rest | (*d & ((1 << (8 - off)) - 1));
- #endif
-       }
- }
- static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
- {
-       lcd_drawchars(x, y, &c, 1);
- }
  /************************************************************************/
  /**  Small utility to check that you got the colours right            */
  /************************************************************************/
@@@ -378,16 -153,6 +153,16 @@@ static int test_colors[N_BLK_HOR * N_BL
        CONSOLE_COLOR_BLUE,     CONSOLE_COLOR_MAGENTA,  CONSOLE_COLOR_CYAN,
  };
  
 +#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);
@@@ -453,11 -218,9 +228,9 @@@ int drv_lcd_init(void
  /*----------------------------------------------------------------------*/
  void lcd_clear(void)
  {
- #if LCD_BPP == LCD_MONOCHROME
-       /* Setting the palette */
-       lcd_initcolregs();
- #elif LCD_BPP == LCD_COLOR8
+       short console_rows, console_cols;
+       int bg_color;
+ #if LCD_BPP == LCD_COLOR8
        /* Setting the palette */
        lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
        lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0);
  #ifndef CONFIG_SYS_WHITE_ON_BLACK
        lcd_setfgcolor(CONSOLE_COLOR_BLACK);
        lcd_setbgcolor(CONSOLE_COLOR_WHITE);
+       bg_color = CONSOLE_COLOR_WHITE;
  #else
        lcd_setfgcolor(CONSOLE_COLOR_WHITE);
        lcd_setbgcolor(CONSOLE_COLOR_BLACK);
+       bg_color = CONSOLE_COLOR_BLACK;
  #endif        /* CONFIG_SYS_WHITE_ON_BLACK */
  
  #ifdef        LCD_TEST_PATTERN
  #else
        /* set framebuffer to background color */
  #if (LCD_BPP != LCD_COLOR32)
-       memset((char *)lcd_base,
-               COLOR_MASK(lcd_color_bg),
-               lcd_line_length * panel_info.vl_row);
+       memset((char *)lcd_base, bg_color, 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);
+               *ppix++ = bg_color;
        }
  #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;
-       console_row = 0;
+ #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+       console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT);
+       console_rows /= VIDEO_FONT_HEIGHT;
+ #else
+       console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT;
+ #endif
+       console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH;
+       lcd_init_console(lcd_base, console_rows, console_cols);
+       lcd_init_console(lcd_logo(), console_rows, console_cols);
        lcd_sync();
  }
  
@@@ -523,9 -291,7 +301,9 @@@ 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_enable();
  
        /* Initialize the console */
-       console_col = 0;
+       lcd_set_col(0);
  #ifdef CONFIG_LCD_INFO_BELOW_LOGO
-       console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
+       lcd_set_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT);
  #else
-       console_row = 1;        /* leave 1 blank line below logo */
+       lcd_set_row(1); /* leave 1 blank line below logo */
  #endif
  
        return 0;
@@@ -597,6 -363,11 +375,11 @@@ static void lcd_setfgcolor(int color
        lcd_color_fg = color;
  }
  
+ int lcd_getfgcolor(void)
+ {
+       return lcd_color_fg;
+ }
  /*----------------------------------------------------------------------*/
  
  static void lcd_setbgcolor(int color)
        lcd_color_bg = color;
  }
  
+ int lcd_getbgcolor(void)
+ {
+       return lcd_color_bg;
+ }
  /************************************************************************/
  /* ** Chipset depending Bitmap / Logo stuff...                          */
  /************************************************************************/
@@@ -613,7 -389,7 +401,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 -416,7 +428,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);
                        *(cmap + BMP_LOGO_OFFSET) = lut_entry;
                        cmap++;
  #else /* !CONFIG_ATMEL_LCD */
- #ifdef  CONFIG_SYS_INVERT_COLORS
-                       *cmap++ = 0xffff - colreg;
- #else
                        *cmap++ = colreg;
- #endif
  #endif /* CONFIG_ATMEL_LCD */
                }
  
                        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();
@@@ -919,12 -677,6 +703,12 @@@ 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)
  {
        ushort *cmap = NULL;
        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;
        }
  
 -      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);
  
 +      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 = colreg;
- #endif
  #if defined(CONFIG_MPC823)
                        cmap--;
  #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
                }
        }
  
 -      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 + 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);
  
                }
  #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;
        }
                        fb -= lcd_line_length + width * (bpix / 8);
                }
                break;
 -#endif /* CONFIG_BMP_24BMP */
 +#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;
  #endif /* CONFIG_BMP_32BPP */
 -      default:
 -              break;
        };
  
 -      lcd_sync();
        return 0;
  }
  #endif
@@@ -1123,16 -859,12 +903,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);
  
        bitmap_plot(0, 0);
  
  #ifdef CONFIG_LCD_INFO
-       console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
-       console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
+       lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH);
+       lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT);
        lcd_show_board_info();
  #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
@@@ -1180,12 -912,6 +960,6 @@@ static int on_splashimage(const char *n
  U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
  #endif
  
- void lcd_position_cursor(unsigned col, unsigned row)
- {
-       console_col = min_t(short, col, CONSOLE_COLS - 1);
-       console_row = min_t(short, row, CONSOLE_ROWS - 1);
- }
  int lcd_get_pixel_width(void)
  {
        return panel_info.vl_col;
@@@ -1196,16 -922,6 +970,6 @@@ int lcd_get_pixel_height(void
        return panel_info.vl_row;
  }
  
- int lcd_get_screen_rows(void)
- {
-       return CONSOLE_ROWS;
- }
- int lcd_get_screen_columns(void)
- {
-       return CONSOLE_COLS;
- }
  #if defined(CONFIG_LCD_DT_SIMPLEFB)
  static int lcd_dt_simplefb_configure_node(void *blob, int off)
  {
diff --combined common/spl/spl.c
index 46447f4905216bb98748794d07752ea8c8121483,daaeb507c467b14cf0f80ecaab46e48064e58672..526bd1a754490c5f93cdd9f0d6786c1b7828dbb2
@@@ -182,9 -182,8 +182,9 @@@ void board_init_r(gd_t *dummy1, ulong d
  #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:
  #endif
        default:
  #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
-               printf("SPL: Unsupported Boot Device %d\n", boot_device);
+               puts("SPL: Unsupported Boot Device!\n");
  #endif
                hang();
        }
index 7d8c361599638c9af6baf590cbf94182a44d1e9a,a69bbd2002e9f62c06f75cb1f1b4b755140eecc2..8ff82c5e62b5c1e62f03026a9979db5900170199
@@@ -7,20 -7,25 +7,25 @@@
  #include <common.h>
  #include <dm.h>
  #include <errno.h>
+ #include <fdtdec.h>
  #include <malloc.h>
  #include <asm/gpio.h>
  #include <linux/ctype.h>
  
+ DECLARE_GLOBAL_DATA_PTR;
  /**
   * 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.
+  *
+  * @gpio:     The numeric representation of the GPIO
+  * @desc:     Returns description (desc->flags will always be 0)
+  * @return 0 if found, -ENOENT if not found
   */
- static int gpio_to_device(unsigned int gpio, struct udevice **devp,
-                         unsigned int *offset)
+ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
  {
        struct gpio_dev_priv *uc_priv;
        struct udevice *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;
+                       desc->dev = dev;
+                       desc->offset = gpio - uc_priv->gpio_base;
+                       desc->flags = 0;
                        return 0;
                }
        }
  
        /* No such GPIO */
-       return ret ? ret : -EINVAL;
+       return ret ? ret : -ENOENT;
  }
  
  int gpio_lookup_name(const char *name, struct udevice **devp,
        return 0;
  }
  
+ static int gpio_find_and_xlate(struct gpio_desc *desc,
+                              struct fdtdec_phandle_args *args)
+ {
+       struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+       /* Use the first argument as the offset by default */
+       if (args->args_count > 0)
+               desc->offset = args->args[0];
+       else
+               desc->offset = -1;
+       desc->flags = 0;
+       return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+ }
+ static int dm_gpio_request(struct gpio_desc *desc, const char *label)
+ {
+       struct udevice *dev = desc->dev;
+       struct gpio_dev_priv *uc_priv;
+       char *str;
+       int ret;
+       uc_priv = dev->uclass_priv;
+       if (uc_priv->name[desc->offset])
+               return -EBUSY;
+       str = strdup(label);
+       if (!str)
+               return -ENOMEM;
+       if (gpio_get_ops(dev)->request) {
+               ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
+               if (ret) {
+                       free(str);
+                       return ret;
+               }
+       }
+       uc_priv->name[desc->offset] = str;
+       return 0;
+ }
+ static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
+ {
+       va_list args;
+       char buf[40];
+       va_start(args, fmt);
+       vscnprintf(buf, sizeof(buf), fmt, args);
+       va_end(args);
+       return dm_gpio_request(desc, buf);
+ }
  /**
   * gpio_request() - [COMPAT] Request GPIO
   * gpio:      GPIO number
   */
  int gpio_request(unsigned gpio, const char *label)
  {
-       struct gpio_dev_priv *uc_priv;
-       unsigned int offset;
-       struct udevice *dev;
-       char *str;
+       struct gpio_desc desc;
        int ret;
  
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
        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;
+       return dm_gpio_request(&desc, label);
  }
  
  /**
@@@ -151,67 -190,11 +190,53 @@@ int gpio_requestf(unsigned gpio, const 
        return gpio_request(gpio, buf);
  }
  
- /**
-  * 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)
 +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;
 +}
 +
+ int _dm_gpio_free(struct udevice *dev, uint offset)
  {
        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;
        return 0;
  }
  
- static int check_reserved(struct udevice *dev, unsigned offset,
-                         const char *func)
 +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;
 +}
 +
+ /**
+  * 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_desc desc;
+       int ret;
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+       return _dm_gpio_free(desc.dev, desc.offset);
+ }
+ static int check_reserved(struct gpio_desc *desc, const char *func)
  {
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv;
  
-       if (!uc_priv->name[offset]) {
+       if (!uc_priv->name[desc->offset]) {
                printf("%s: %s: error: gpio %s%d not reserved\n",
-                      dev->name, func,
-                      uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+                      desc->dev->name, func,
+                      uc_priv->bank_name ? uc_priv->bank_name : "",
+                      desc->offset);
                return -EBUSY;
        }
  
   */
  int gpio_direction_input(unsigned gpio)
  {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
        int ret;
  
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+       ret = check_reserved(&desc, "dir_input");
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "dir_input");
  
-       return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
+       return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
  }
  
  /**
   */
  int gpio_direction_output(unsigned gpio, int value)
  {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
+       int ret;
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+       ret = check_reserved(&desc, "dir_output");
+       if (ret)
+               return ret;
+       return gpio_get_ops(desc.dev)->direction_output(desc.dev,
+                                                       desc.offset, value);
+ }
+ int dm_gpio_get_value(struct gpio_desc *desc)
+ {
+       int value;
+       int ret;
+       ret = check_reserved(desc, "get_value");
+       if (ret)
+               return ret;
+       value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
+       return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
+ }
+ int dm_gpio_set_value(struct gpio_desc *desc, int value)
+ {
        int ret;
  
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = check_reserved(desc, "set_value");
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "dir_output");
  
-       return ret ? ret :
-               gpio_get_ops(dev)->direction_output(dev, offset, value);
+       if (desc->flags & GPIOD_ACTIVE_LOW)
+               value = !value;
+       gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
+       return 0;
+ }
+ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+ {
+       struct udevice *dev = desc->dev;
+       struct dm_gpio_ops *ops = gpio_get_ops(dev);
+       int ret;
+       ret = check_reserved(desc, "set_dir");
+       if (ret)
+               return ret;
+       if (flags & GPIOD_IS_OUT) {
+               int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
+               if (flags & GPIOD_ACTIVE_LOW)
+                       value = !value;
+               ret = ops->direction_output(dev, desc->offset, value);
+       } else  if (flags & GPIOD_IS_IN) {
+               ret = ops->direction_input(dev, desc->offset);
+       }
+       if (ret)
+               return ret;
+       /*
+        * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
+        * futures
+        */
+       desc->flags = flags;
+       return 0;
+ }
+ int dm_gpio_set_dir(struct gpio_desc *desc)
+ {
+       return dm_gpio_set_dir_flags(desc, desc->flags);
  }
  
  /**
   */
  int gpio_get_value(unsigned gpio)
  {
-       unsigned int offset;
-       struct udevice *dev;
        int ret;
  
-       ret = gpio_to_device(gpio, &dev, &offset);
+       struct gpio_desc desc;
+       ret = gpio_to_device(gpio, &desc);
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "get_value");
-       return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
+       return dm_gpio_get_value(&desc);
  }
  
  /**
   */
  int gpio_set_value(unsigned gpio, int value)
  {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
        int ret;
  
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "set_value");
-       return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
+       return dm_gpio_set_value(&desc, value);
  }
  
  const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
@@@ -462,6 -514,155 +567,155 @@@ unsigned gpio_get_values_as_int(const i
        return vector;
  }
  
+ static int _gpio_request_by_name_nodev(const void *blob, int node,
+                                      const char *list_name, int index,
+                                      struct gpio_desc *desc, int flags,
+                                      bool add_index)
+ {
+       struct fdtdec_phandle_args args;
+       int ret;
+       desc->dev = NULL;
+       desc->offset = 0;
+       ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
+                                            "#gpio-cells", 0, index, &args);
+       if (ret) {
+               debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+               goto err;
+       }
+       ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
+                                            &desc->dev);
+       if (ret) {
+               debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
+               goto err;
+       }
+       ret = gpio_find_and_xlate(desc, &args);
+       if (ret) {
+               debug("%s: gpio_find_and_xlate failed\n", __func__);
+               goto err;
+       }
+       ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
+                              fdt_get_name(blob, node, NULL),
+                              list_name, index);
+       if (ret) {
+               debug("%s: dm_gpio_requestf failed\n", __func__);
+               goto err;
+       }
+       ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+       if (ret) {
+               debug("%s: dm_gpio_set_dir failed\n", __func__);
+               goto err;
+       }
+       return 0;
+ err:
+       debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
+             __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
+       return ret;
+ }
+ int gpio_request_by_name_nodev(const void *blob, int node,
+                              const char *list_name, int index,
+                              struct gpio_desc *desc, int flags)
+ {
+       return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
+                                          flags, index > 0);
+ }
+ int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
+                        struct gpio_desc *desc, int flags)
+ {
+       /*
+        * This isn't ideal since we don't use dev->name in the debug()
+        * calls in gpio_request_by_name(), but we can do this until
+        * gpio_request_by_name_nodev() can be dropped.
+        */
+       return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
+                                         list_name, index, desc, flags);
+ }
+ int gpio_request_list_by_name_nodev(const void *blob, int node,
+                                   const char *list_name,
+                                   struct gpio_desc *desc, int max_count,
+                                   int flags)
+ {
+       int count;
+       int ret;
+       for (count = 0; ; count++) {
+               if (count >= max_count) {
+                       ret = -ENOSPC;
+                       goto err;
+               }
+               ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
+                                                 &desc[count], flags, true);
+               if (ret == -ENOENT)
+                       break;
+               else if (ret)
+                       goto err;
+       }
+       /* We ran out of GPIOs in the list */
+       return count;
+ err:
+       gpio_free_list_nodev(desc, count - 1);
+       return ret;
+ }
+ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+                             struct gpio_desc *desc, int max_count,
+                             int flags)
+ {
+       /*
+        * This isn't ideal since we don't use dev->name in the debug()
+        * calls in gpio_request_by_name(), but we can do this until
+        * gpio_request_list_by_name_nodev() can be dropped.
+        */
+       return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
+                                              list_name, desc, max_count,
+                                              flags);
+ }
+ int gpio_get_list_count(struct udevice *dev, const char *list_name)
+ {
+       int ret;
+       ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+                                            list_name, "#gpio-cells", 0, -1,
+                                            NULL);
+       if (ret) {
+               debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
+                     __func__, dev->name, list_name, ret);
+       }
+       return ret;
+ }
+ int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
+ {
+       /* For now, we don't do any checking of dev */
+       return _dm_gpio_free(desc->dev, desc->offset);
+ }
+ int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
+ {
+       int i;
+       /* For now, we don't do any checking of dev */
+       for (i = 0; i < count; i++)
+               dm_gpio_free(dev, &desc[i]);
+       return 0;
+ }
+ int gpio_free_list_nodev(struct gpio_desc *desc, int count)
+ {
+       return gpio_free_list(NULL, desc, count);
+ }
  /* We need to renumber the GPIOs when any driver is probed/removed */
  static int gpio_renumber(struct udevice *removed_dev)
  {
diff --combined drivers/i2c/Kconfig
index e059df992a19f05c849d0a5c5fb5550074fedfc8,202ea5d67940ece1c555568794a7cfd343f0fc30..8babe12159fee027a7c24559141aba7e4fe52756
@@@ -1,14 -1,22 +1,36 @@@
+ config DM_I2C
+       bool "Enable Driver Model for I2C drivers"
+       depends on DM
+       help
+         If you want to use driver model for I2C drivers, say Y.
+         To use legacy I2C drivers, say N.
+ config SYS_I2C_UNIPHIER
+       bool "UniPhier I2C driver"
+       depends on ARCH_UNIPHIER && DM_I2C
+       default y
+       help
+         Support for Panasonic UniPhier I2C controller driver.  This I2C
+         controller is used on PH1-LD4, PH1-sLD8 or older UniPhier SoCs.
+ config SYS_I2C_UNIPHIER_F
+       bool "UniPhier FIFO-builtin I2C driver"
+       depends on ARCH_UNIPHIER && DM_I2C
+       default y
+       help
+         Support for Panasonic UniPhier FIFO-builtin I2C controller driver.
+         This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs.
 +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/mmc/Kconfig
index 699f861843b540c960435e571885624c6d2ecf34,7ba85a2b62c45b5f968dbddc1994d7f174163e9a..b52100c2c51c21c19087b085257fda95752ef9e3
@@@ -1,23 -1,9 +1,29 @@@
- menuconfig MMC
-       bool "MMC/SD device support"
-       select CMD_MMC
+ menu "MMC Host controller Support"
  
- if MMC
++config MMC
++      bool
 +
 +config GENERIC_MMC
 +      bool
++      select MMC
++
+ config SH_SDHI
+       bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
+       depends on RMOBILE
+       help
+         Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
  
- endif
 +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
 +
+ endmenu
diff --combined drivers/mmc/mmc.c
index 88c0206b1a92c795640a5da00f2cbdd7f300cb8c,b8039cd092abd43a14022f0a1e7a646198c30aa6..85e9509ed19374115421bcc6fc5ba10c380f0a24
@@@ -324,7 -324,8 +324,7 @@@ static int sd_send_op_cond(struct mmc *
  
                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)
@@@ -382,7 -383,7 +382,7 @@@ static int mmc_send_op_cond(struct mmc 
        /* 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);
@@@ -410,13 -411,9 +410,13 @@@ static int mmc_complete_op_cond(struct 
                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;
@@@ -489,7 -486,7 +489,7 @@@ static int mmc_change_freq(struct mmc *
        char cardtype;
        int err;
  
-       mmc->card_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
+       mmc->card_caps = 0;
  
        if (mmc_host_is_spi(mmc))
                return 0;
        if (mmc->version < MMC_VERSION_4)
                return 0;
  
+       mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
        err = mmc_send_ext_csd(mmc, ext_csd);
  
        if (err)
@@@ -608,6 -607,200 +610,200 @@@ int mmc_switch_part(int dev_num, unsign
        return ret;
  }
  
+ int mmc_hwpart_config(struct mmc *mmc,
+                     const struct mmc_hwpart_conf *conf,
+                     enum mmc_hwpart_conf_mode mode)
+ {
+       u8 part_attrs = 0;
+       u32 enh_size_mult;
+       u32 enh_start_addr;
+       u32 gp_size_mult[4];
+       u32 max_enh_size_mult;
+       u32 tot_enh_size_mult = 0;
+       u8 wr_rel_set;
+       int i, pidx, err;
+       ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+       if (mode < MMC_HWPART_CONF_CHECK || mode > MMC_HWPART_CONF_COMPLETE)
+               return -EINVAL;
+       if (IS_SD(mmc) || (mmc->version < MMC_VERSION_4_41)) {
+               printf("eMMC >= 4.4 required for enhanced user data area\n");
+               return -EMEDIUMTYPE;
+       }
+       if (!(mmc->part_support & PART_SUPPORT)) {
+               printf("Card does not support partitioning\n");
+               return -EMEDIUMTYPE;
+       }
+       if (!mmc->hc_wp_grp_size) {
+               printf("Card does not define HC WP group size\n");
+               return -EMEDIUMTYPE;
+       }
+       /* check partition alignment and total enhanced size */
+       if (conf->user.enh_size) {
+               if (conf->user.enh_size % mmc->hc_wp_grp_size ||
+                   conf->user.enh_start % mmc->hc_wp_grp_size) {
+                       printf("User data enhanced area not HC WP group "
+                              "size aligned\n");
+                       return -EINVAL;
+               }
+               part_attrs |= EXT_CSD_ENH_USR;
+               enh_size_mult = conf->user.enh_size / mmc->hc_wp_grp_size;
+               if (mmc->high_capacity) {
+                       enh_start_addr = conf->user.enh_start;
+               } else {
+                       enh_start_addr = (conf->user.enh_start << 9);
+               }
+       } else {
+               enh_size_mult = 0;
+               enh_start_addr = 0;
+       }
+       tot_enh_size_mult += enh_size_mult;
+       for (pidx = 0; pidx < 4; pidx++) {
+               if (conf->gp_part[pidx].size % mmc->hc_wp_grp_size) {
+                       printf("GP%i partition not HC WP group size "
+                              "aligned\n", pidx+1);
+                       return -EINVAL;
+               }
+               gp_size_mult[pidx] = conf->gp_part[pidx].size / mmc->hc_wp_grp_size;
+               if (conf->gp_part[pidx].size && conf->gp_part[pidx].enhanced) {
+                       part_attrs |= EXT_CSD_ENH_GP(pidx);
+                       tot_enh_size_mult += gp_size_mult[pidx];
+               }
+       }
+       if (part_attrs && ! (mmc->part_support & ENHNCD_SUPPORT)) {
+               printf("Card does not support enhanced attribute\n");
+               return -EMEDIUMTYPE;
+       }
+       err = mmc_send_ext_csd(mmc, ext_csd);
+       if (err)
+               return err;
+       max_enh_size_mult =
+               (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+2] << 16) +
+               (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT+1] << 8) +
+               ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT];
+       if (tot_enh_size_mult > max_enh_size_mult) {
+               printf("Total enhanced size exceeds maximum (%u > %u)\n",
+                      tot_enh_size_mult, max_enh_size_mult);
+               return -EMEDIUMTYPE;
+       }
+       /* The default value of EXT_CSD_WR_REL_SET is device
+        * dependent, the values can only be changed if the
+        * EXT_CSD_HS_CTRL_REL bit is set. The values can be
+        * changed only once and before partitioning is completed. */
+       wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
+       if (conf->user.wr_rel_change) {
+               if (conf->user.wr_rel_set)
+                       wr_rel_set |= EXT_CSD_WR_DATA_REL_USR;
+               else
+                       wr_rel_set &= ~EXT_CSD_WR_DATA_REL_USR;
+       }
+       for (pidx = 0; pidx < 4; pidx++) {
+               if (conf->gp_part[pidx].wr_rel_change) {
+                       if (conf->gp_part[pidx].wr_rel_set)
+                               wr_rel_set |= EXT_CSD_WR_DATA_REL_GP(pidx);
+                       else
+                               wr_rel_set &= ~EXT_CSD_WR_DATA_REL_GP(pidx);
+               }
+       }
+       if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET] &&
+           !(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) {
+               puts("Card does not support host controlled partition write "
+                    "reliability settings\n");
+               return -EMEDIUMTYPE;
+       }
+       if (ext_csd[EXT_CSD_PARTITION_SETTING] &
+           EXT_CSD_PARTITION_SETTING_COMPLETED) {
+               printf("Card already partitioned\n");
+               return -EPERM;
+       }
+       if (mode == MMC_HWPART_CONF_CHECK)
+               return 0;
+       /* Partitioning requires high-capacity size definitions */
+       if (!(ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01)) {
+               err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_ERASE_GROUP_DEF, 1);
+               if (err)
+                       return err;
+               ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
+               /* update erase group size to be high-capacity */
+               mmc->erase_grp_size =
+                       ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
+       }
+       /* all OK, write the configuration */
+       for (i = 0; i < 4; i++) {
+               err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_ENH_START_ADDR+i,
+                                (enh_start_addr >> (i*8)) & 0xFF);
+               if (err)
+                       return err;
+       }
+       for (i = 0; i < 3; i++) {
+               err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_ENH_SIZE_MULT+i,
+                                (enh_size_mult >> (i*8)) & 0xFF);
+               if (err)
+                       return err;
+       }
+       for (pidx = 0; pidx < 4; pidx++) {
+               for (i = 0; i < 3; i++) {
+                       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                                        EXT_CSD_GP_SIZE_MULT+pidx*3+i,
+                                        (gp_size_mult[pidx] >> (i*8)) & 0xFF);
+                       if (err)
+                               return err;
+               }
+       }
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                        EXT_CSD_PARTITIONS_ATTRIBUTE, part_attrs);
+       if (err)
+               return err;
+       if (mode == MMC_HWPART_CONF_SET)
+               return 0;
+       /* The WR_REL_SET is a write-once register but shall be
+        * written before setting PART_SETTING_COMPLETED. As it is
+        * write-once we can only write it when completing the
+        * partitioning. */
+       if (wr_rel_set != ext_csd[EXT_CSD_WR_REL_SET]) {
+               err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_WR_REL_SET, wr_rel_set);
+               if (err)
+                       return err;
+       }
+       /* Setting PART_SETTING_COMPLETED confirms the partition
+        * configuration but it only becomes effective after power
+        * cycle, so we do not adjust the partition related settings
+        * in the mmc struct. */
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                        EXT_CSD_PARTITION_SETTING,
+                        EXT_CSD_PARTITION_SETTING_COMPLETED);
+       if (err)
+               return err;
+       return 0;
+ }
  int mmc_getcd(struct mmc *mmc)
  {
        int cd;
@@@ -821,6 -1014,8 +1017,8 @@@ static int mmc_startup(struct mmc *mmc
        ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
        ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
        int timeout = 1000;
+       bool has_parts = false;
+       bool part_completed;
  
  #ifdef CONFIG_MMC_SPI_CRC_ON
        if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
        if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
                /* check  ext_csd version and capacity */
                err = mmc_send_ext_csd(mmc, ext_csd);
-               if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
+               if (err)
+                       return err;
+               if (ext_csd[EXT_CSD_REV] >= 2) {
                        /*
                         * According to the JEDEC Standard, the value of
                         * ext_csd's capacity is valid if the value is more
                        break;
                }
  
+               /* The partition data may be non-zero but it is only
+                * effective if PARTITION_SETTING_COMPLETED is set in
+                * EXT_CSD, so ignore any data if this bit is not set,
+                * except for enabling the high-capacity group size
+                * definition (see below). */
+               part_completed = !!(ext_csd[EXT_CSD_PARTITION_SETTING] &
+                                   EXT_CSD_PARTITION_SETTING_COMPLETED);
+               /* store the partition info of emmc */
+               mmc->part_support = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
+               if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
+                   ext_csd[EXT_CSD_BOOT_MULT])
+                       mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
+               if (part_completed &&
+                   (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & ENHNCD_SUPPORT))
+                       mmc->part_attr = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
+               mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
+               mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+               for (i = 0; i < 4; i++) {
+                       int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
+                       uint mult = (ext_csd[idx + 2] << 16) +
+                               (ext_csd[idx + 1] << 8) + ext_csd[idx];
+                       if (mult)
+                               has_parts = true;
+                       if (!part_completed)
+                               continue;
+                       mmc->capacity_gp[i] = mult;
+                       mmc->capacity_gp[i] *=
+                               ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+                       mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+                       mmc->capacity_gp[i] <<= 19;
+               }
+               if (part_completed) {
+                       mmc->enh_user_size =
+                               (ext_csd[EXT_CSD_ENH_SIZE_MULT+2] << 16) +
+                               (ext_csd[EXT_CSD_ENH_SIZE_MULT+1] << 8) +
+                               ext_csd[EXT_CSD_ENH_SIZE_MULT];
+                       mmc->enh_user_size *= ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+                       mmc->enh_user_size *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+                       mmc->enh_user_size <<= 19;
+                       mmc->enh_user_start =
+                               (ext_csd[EXT_CSD_ENH_START_ADDR+3] << 24) +
+                               (ext_csd[EXT_CSD_ENH_START_ADDR+2] << 16) +
+                               (ext_csd[EXT_CSD_ENH_START_ADDR+1] << 8) +
+                               ext_csd[EXT_CSD_ENH_START_ADDR];
+                       if (mmc->high_capacity)
+                               mmc->enh_user_start <<= 9;
+               }
                /*
                 * 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 (part_completed)
+                       has_parts = true;
                if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
-                   (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
+                   (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB))
+                       has_parts = true;
+               if (has_parts) {
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
                                EXT_CSD_ERASE_GROUP_DEF, 1);
  
                                return err;
                        else
                                ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
+               }
  
+               if (ext_csd[EXT_CSD_ERASE_GROUP_DEF] & 0x01) {
                        /* Read out group size from ext_csd */
                        mmc->erase_grp_size =
-                               ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
-                                       MMC_MAX_BLOCK_LEN * 1024;
+                               ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 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)) {
+                       if (mmc->high_capacity && part_completed) {
                                capacity = (ext_csd[EXT_CSD_SEC_CNT]) |
                                        (ext_csd[EXT_CSD_SEC_CNT + 1] << 8) |
                                        (ext_csd[EXT_CSD_SEC_CNT + 2] << 16) |
                                * (erase_gmul + 1);
                }
  
-               /* store the partition info of emmc */
-               if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
-                   ext_csd[EXT_CSD_BOOT_MULT])
-                       mmc->part_config = ext_csd[EXT_CSD_PART_CONF];
-               mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17;
-               mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17;
+               mmc->hc_wp_grp_size = 1024
+                       * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+                       * ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
  
-               for (i = 0; i < 4; i++) {
-                       int idx = EXT_CSD_GP_SIZE_MULT + i * 3;
-                       mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) +
-                               (ext_csd[idx + 1] << 8) + ext_csd[idx];
-                       mmc->capacity_gp[i] *=
-                               ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
-                       mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
-               }
+               mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
        }
  
        err = mmc_set_capacity(mmc, mmc->part_num);
                        mmc->tran_speed = 50000000;
                else
                        mmc->tran_speed = 25000000;
-       } else {
+       } else if (mmc->version >= MMC_VERSION_4) {
+               /* Only version 4 of MMC supports wider bus widths */
                int idx;
  
                /* An array of possible bus widths in order of preference */
                        unsigned int extw = ext_csd_bits[idx];
                        unsigned int caps = ext_to_hostcaps[extw];
  
+                       /*
+                        * If the bus width is still not changed,
+                        * don't try to set the default again.
+                        * Otherwise, recover from switch attempts
+                        * by switching to 1-bit bus width.
+                        */
+                       if (extw == EXT_CSD_BUS_WIDTH_1 &&
+                                       mmc->bus_width == 1) {
+                               err = 0;
+                               break;
+                       }
                        /*
                         * Check to make sure the card and controller support
                         * these capabilities
diff --combined drivers/mmc/omap_hsmmc.c
index 995ec2c0952483e8e0eb948972766e9747c04259,dc725cb5b0d83428a6d8e6b65b180aa413f08c95..813b90946cacd4a3ad47c9c457cb1958a5696235
@@@ -125,7 -125,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);
+ #ifdef CONFIG_TARGET_OMAP3_CAIRO
+       /* for cairo board, we need to set up 1.8 Volt bias level on MMC1 */
+       pbias_lite &= ~PBIASLITEVMODE0;
+ #endif
        writel(pbias_lite, &t2_base->pbias_lite);
  
        writel(pbias_lite | PBIASLITEPWRDNZ1 |
        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 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);
  
@@@ -311,41 -307,38 +315,41 @@@ static void mmc_reset_controller_fsm(st
  #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 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->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);
@@@ -458,15 -450,14 +462,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);
@@@ -514,15 -505,14 +518,15 @@@ static int mmc_write_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);
  
  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);
  }
@@@ -654,22 -642,21 +658,22 @@@ static const struct mmc_ops omap_hsmmc_
  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;
        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:
                break;
  #endif
        default:
 -              priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
 -              return 1;
 +              printf("Invalid MMC device index: %d\n", dev_index);
 +              ret = 1;
 +              goto out;
        }
  #ifdef OMAP_HSMMC_USE_GPIO
        /* on error gpio values are set to -1, which is what we want */
                cfg->b_max = 1;
  #endif
        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;
  }
index fa8dace7e9dd5b8f6c2fd93586d1a40219ea05b4,6db6566e733656d55a88c024bd1b07b5c6d58c3c..5aaea904c204bed97273f495a5ed331a77e9ebdf
@@@ -1065,11 -1065,6 +1065,6 @@@ static int nand_wait(struct mtd_info *m
                }
        }
  #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);
@@@ -2513,7 -2508,7 +2508,7 @@@ 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
@@@ -4260,8 -4255,6 +4255,8 @@@ int nand_scan_tail(struct mtd_info *mtd
        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();
        }
        ecc->total = ecc->steps * ecc->bytes;
index 94c18c97d030919f2d87325c028c1bbe1e028cfc,fc64f4814484e8052410f4769c60240ae67dc510..9c56bd3a55c09af46a61ec5c88e74acb54061b50
@@@ -42,190 -42,6 +42,190 @@@ struct omap_nand_info 
  /* 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
@@@ -260,7 -76,7 +260,7 @@@ static void omap_nand_hwcontrol(struct 
  /* Check wait pin as dev ready indicator */
  static int omap_dev_ready(struct mtd_info *mtd)
  {
 -      return gpmc_cfg->status & (1 << 8);
 +      return readl(&gpmc_cfg->status) & (1 << 8);
  }
  
  /*
@@@ -625,6 -441,115 +625,115 @@@ static int omap_correct_data_bch(struc
        return (err) ? err : error_count;
  }
  
+ #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
+ #define PREFETCH_CONFIG1_CS_SHIFT     24
+ #define PREFETCH_FIFOTHRESHOLD_MAX    0x40
+ #define PREFETCH_FIFOTHRESHOLD(val)   ((val) << 8)
+ #define PREFETCH_STATUS_COUNT(val)    (val & 0x00003fff)
+ #define PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
+ #define ENABLE_PREFETCH                       (1 << 7)
+ /**
+  * omap_prefetch_enable - configures and starts prefetch transfer
+  * @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
+  * @cs: chip select to use
+  */
+ static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write, int cs)
+ {
+       uint32_t val;
+       if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX)
+               return -EINVAL;
+       if (readl(&gpmc_cfg->prefetch_control))
+               return -EBUSY;
+       /* Set the amount of bytes to be prefetched */
+       writel(count, &gpmc_cfg->prefetch_config2);
+       val = (cs << PREFETCH_CONFIG1_CS_SHIFT) | (is_write & 1) |
+               PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH;
+       writel(val, &gpmc_cfg->prefetch_config1);
+       /*  Start the prefetch engine */
+       writel(1, &gpmc_cfg->prefetch_control);
+       return 0;
+ }
+ /**
+  * omap_prefetch_reset - disables and stops the prefetch engine
+  */
+ static void omap_prefetch_reset(void)
+ {
+       writel(0, &gpmc_cfg->prefetch_control);
+       writel(0, &gpmc_cfg->prefetch_config1);
+ }
+ static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len)
+ {
+       int ret;
+       uint32_t cnt;
+       struct omap_nand_info *info = chip->priv;
+       ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
+       if (ret < 0)
+               return ret;
+       do {
+               int i;
+               cnt = readl(&gpmc_cfg->prefetch_status);
+               cnt = PREFETCH_STATUS_FIFO_CNT(cnt);
+               for (i = 0; i < cnt / 4; i++) {
+                       *buf++ = readl(CONFIG_SYS_NAND_BASE);
+                       len -= 4;
+               }
+       } while (len);
+       omap_prefetch_reset();
+       return 0;
+ }
+ static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len)
+ {
+       int ret;
+       uint32_t head, tail;
+       struct nand_chip *chip = mtd->priv;
+       /*
+        * If the destination buffer is unaligned, start with reading
+        * the overlap byte-wise.
+        */
+       head = ((uint32_t) buf) % 4;
+       if (head) {
+               nand_read_buf(mtd, buf, head);
+               buf += head;
+               len -= head;
+       }
+       /*
+        * Only transfer multiples of 4 bytes in a pre-fetched fashion.
+        * If there's a residue, care for it byte-wise afterwards.
+        */
+       tail = len % 4;
+       ret = __read_prefetch_aligned(chip, (uint32_t *) buf, len - tail);
+       if (ret < 0) {
+               /* fallback in case the prefetch engine is busy */
+               nand_read_buf(mtd, buf, len);
+       } else if (tail) {
+               buf += len - tail;
+               nand_read_buf(mtd, buf, tail);
+       }
+ }
+ #endif /* CONFIG_NAND_OMAP_GPMC_PREFETCH */
  /**
   * omap_read_page_bch - hardware ecc based page read function
   * @mtd:      mtd info structure
@@@ -644,13 -569,14 +753,13 @@@ 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) {
                /* read syndrome */
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
  
 +              if (oob_required) {
 +                      /* reread the OOB area to get the metadata */
 +                      chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, page);
 +                      chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 +              }
 +
                data_pos += eccsize;
                oob_pos += eccbytes;
        }
@@@ -724,22 -644,22 +833,22 @@@ static int omap_correct_data_bch_sw(str
                                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;
  }
@@@ -1068,27 -988,13 +1177,28 @@@ int board_nand_init(struct nand_chip *n
  #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
+ #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
+       /* TODO: Implement for 16-bit bus width */
        if (nand->options & NAND_BUSWIDTH_16)
                nand->read_buf = nand_read_buf16;
        else
-               nand->read_buf = nand_read_buf;
+               nand->read_buf = omap_nand_read_prefetch8;
  #endif
  
        nand->dev_ready = omap_dev_ready;
diff --combined drivers/net/phy/phy.c
index a8ef661b3edb2ce897f8d6b91fd8a65fa3c37548,df7e9450c2614a4040ced79d12d0e21238e5f689..d35e35f7eddf601d58980557b14bd1df65de982d
@@@ -44,6 -44,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;
  
@@@ -78,6 -79,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);
  }
  
  
@@@ -135,6 -140,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);
  }
  
  
@@@ -197,16 -205,13 +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;
@@@ -281,14 -275,10 +281,14 @@@ 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 (phydev->supported & SUPPORTED_Autoneg) {
 +              int ret;
                u32 lpa = 0;
 -              int gblpa = 0;
 +              u32 gblpa = 0;
                u32 estatus = 0;
  
                /* Check for gigabit capability */
                        /* 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) {
                                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;
@@@ -401,6 -375,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;
  
@@@ -467,6 -442,9 +467,9 @@@ static LIST_HEAD(phy_drivers)
  
  int phy_init(void)
  {
+ #ifdef CONFIG_PHY_AQUANTIA
+       phy_aquantia_init();
+ #endif
  #ifdef CONFIG_PHY_ATHEROS
        phy_atheros_init();
  #endif
@@@ -558,69 -536,6 +561,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;
@@@ -788,7 -674,6 +791,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;
index 0d87e508c0d9bc66f9a324e9e781df755084ca52,3b96b8209a10b09d2cdcdf1f559c5fa2787831d7..d4f4f0685b96e3d872870eb77725c44d4f2d27cc
  /*
   * Generic GPIO API for U-Boot
   *
+  * --
+  * NB: This is deprecated. Please use the driver model functions instead:
+  *
+  *    - gpio_request_by_name()
+  *    - dm_gpio_get_value() etc.
+  *
+  * For now we need a dm_ prefix on some functions to avoid name collision.
+  * --
+  *
   * GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined
   * by the SOC/architecture.
   *
   * an error value of -1.
   */
  
 +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;
 +};
 +
  /**
+  * @deprecated        Please use driver model instead
   * Request a GPIO. This should be called before any of the other functions
   * are used on this GPIO.
   *
   */
  int gpio_request(unsigned gpio, const char *label);
  
 +/**
++ * @deprecated        Please use driver model instead
 + * 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);
 +
  /**
+  * @deprecated        Please use driver model instead
   * Stop using the GPIO.  This function should not alter pin configuration.
   *
   * @param gpio        GPIO number
   */
  int gpio_free(unsigned gpio);
  
 +/**
++ * @deprecated        Please use driver model instead
 + * 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);
 +
  /**
+  * @deprecated        Please use driver model instead
   * Make a GPIO an input.
   *
   * @param gpio        GPIO number
  int gpio_direction_input(unsigned gpio);
  
  /**
+  * @deprecated        Please use driver model instead
   * Make a GPIO an output, and set its value.
   *
   * @param gpio        GPIO number
  int gpio_direction_output(unsigned gpio, int value);
  
  /**
+  * @deprecated        Please use driver model instead
   * Get a GPIO's value. This will work whether the GPIO is an input
   * or an output.
   *
  int gpio_get_value(unsigned gpio);
  
  /**
+  * @deprecated        Please use driver model instead
   * Set an output GPIO's value. The GPIO must already be an output or
   * this function may have no effect.
   *
@@@ -128,6 -110,34 +145,34 @@@ enum gpio_func_t 
  
  struct udevice;
  
+ struct gpio_desc {
+       struct udevice *dev;    /* Device, NULL for invalid GPIO */
+       unsigned long flags;
+ #define GPIOD_REQUESTED               (1 << 0)        /* Requested/claimed */
+ #define GPIOD_IS_OUT          (1 << 1)        /* GPIO is an output */
+ #define GPIOD_IS_IN           (1 << 2)        /* GPIO is an output */
+ #define GPIOD_ACTIVE_LOW      (1 << 3)        /* value has active low */
+ #define GPIOD_IS_OUT_ACTIVE   (1 << 4)        /* set output active */
+       uint offset;            /* GPIO offset within the device */
+       /*
+        * We could consider adding the GPIO label in here. Possibly we could
+        * use this structure for internal GPIO information.
+        */
+ };
+ /**
+  * dm_gpio_is_valid() - Check if a GPIO is gpio_is_valie
+  *
+  * @desc:     GPIO description containing device, offset and flags,
+  *            previously returned by gpio_request_by_name()
+  * @return true if valid, false if not
+  */
+ static inline bool dm_gpio_is_valid(struct gpio_desc *desc)
+ {
+       return desc->dev != NULL;
+ }
  /**
   * gpio_get_status() - get the current GPIO status as a string
   *
   * 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'
   *
+  * TODO(sjg@chromium.org): This should use struct gpio_desc
+  *
   * @dev:      Device to check
   * @offset:   Offset of device GPIO to check
   * @buf:      Place to put string
@@@ -151,6 -163,8 +198,8 @@@ int gpio_get_status(struct udevice *dev
   *
   * Note this returns GPIOF_UNUSED if the GPIO is not requested.
   *
+  * TODO(sjg@chromium.org): This should use struct gpio_desc
+  *
   * @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
@@@ -168,6 -182,8 +217,8 @@@ int gpio_get_function(struct udevice *d
   * 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.
   *
+  * TODO(sjg@chromium.org): This should use struct gpio_desc
+  *
   * @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
@@@ -188,6 -204,8 +239,8 @@@ int gpio_get_raw_function(struct udevic
  int gpio_requestf(unsigned gpio, const char *fmt, ...)
                __attribute__ ((format (__printf__, 2, 3)));
  
+ struct fdtdec_phandle_args;
  /**
   * struct struct dm_gpio_ops - Driver model GPIO operations
   *
@@@ -231,6 -249,33 +284,33 @@@ struct dm_gpio_ops 
         * @return current function - GPIOF_...
         */
        int (*get_function)(struct udevice *dev, unsigned offset);
+       /**
+        * xlate() - Translate phandle arguments into a GPIO description
+        *
+        * This function should set up the fields in desc according to the
+        * information in the arguments. The uclass will have set up:
+        *
+        *   @desc->dev to @dev
+        *   @desc->flags to 0
+        *   @desc->offset to the value of the first argument in args, if any,
+        *              otherwise -1 (which is invalid)
+        *
+        * This method is optional so if the above defaults suit it can be
+        * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
+        * in desc->flags.
+        *
+        * Note that @dev is passed in as a parameter to follow driver model
+        * uclass conventions, even though it is already available as
+        * desc->dev.
+        *
+        * @dev:        GPIO device
+        * @desc:       Place to put GPIO description
+        * @args:       Arguments provided in descripion
+        * @return 0 if OK, -ve on error
+        */
+       int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
+                    struct fdtdec_phandle_args *args);
  };
  
  /**
@@@ -301,4 -346,191 +381,191 @@@ int gpio_lookup_name(const char *name, 
   */
  unsigned gpio_get_values_as_int(const int *gpio_list);
  
+ /**
+  * gpio_request_by_name() - Locate and request a GPIO by name
+  *
+  * This operates by looking up the given list name in the device (device
+  * tree property) and requesting the GPIO for use. The property must exist
+  * in @dev's node.
+  *
+  * Use @flags to specify whether the GPIO should be an input or output. In
+  * principle this can also come from the device tree binding but most
+  * bindings don't provide this information. Specifically, when the GPIO uclass
+  * calls the xlate() method, it can return default flags, which are then
+  * ORed with this @flags.
+  *
+  * If we find that requesting the GPIO is not always needed we could add a
+  * new function or a new GPIOD_NO_REQUEST flag.
+  *
+  * At present driver model has no reference counting so if one device
+  * requests a GPIO which subsequently is unbound, the @desc->dev pointer
+  * will be invalid. However this will only happen if the GPIO device is
+  * unbound, not if it is removed, so this seems like a reasonable limitation
+  * for now. There is no real use case for unbinding drivers in normal
+  * operation.
+  *
+  * The device tree binding is doc/device-tree-bindings/gpio/gpio.txt in
+  * generate terms and each specific device may add additional details in
+  * a binding file in the same directory.
+  *
+  * @dev:      Device requesting the GPIO
+  * @list_name:        Name of GPIO list (e.g. "board-id-gpios")
+  * @index:    Index number of the GPIO in that list use request (0=first)
+  * @desc:     Returns GPIO description information. If there is no such
+  *            GPIO, dev->dev will be NULL.
+  * @flags:    Indicates the GPIO input/output settings (GPIOD_...)
+  * @return 0 if OK, -ENOENT if the GPIO does not exist, -EINVAL if there is
+  * something wrong with the list, or other -ve for another error (e.g.
+  * -EBUSY if a GPIO was already requested)
+  */
+ int gpio_request_by_name(struct udevice *dev, const char *list_name,
+                        int index, struct gpio_desc *desc, int flags);
+ /**
+  * gpio_request_list_by_name() - Request a list of GPIOs
+  *
+  * Reads all the GPIOs from a list and requetss them. See
+  * gpio_request_by_name() for additional details. Lists should not be
+  * misused to hold unrelated or optional GPIOs. They should only be used
+  * for things like parallel data lines. A zero phandle terminates the list
+  * the list.
+  *
+  * This function will either succeed, and request all GPIOs in the list, or
+  * fail and request none (it will free already-requested GPIOs in case of
+  * an error part-way through).
+  *
+  * @dev:      Device requesting the GPIO
+  * @list_name:        Name of GPIO list (e.g. "board-id-gpios")
+  * @desc_list:        Returns a list of GPIO description information
+  * @max_count:        Maximum number of GPIOs to return (@desc_list must be at least
+  *            this big)
+  * @flags:    Indicates the GPIO input/output settings (GPIOD_...)
+  * @return number of GPIOs requested, or -ve on error
+  */
+ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+                             struct gpio_desc *desc_list, int max_count,
+                             int flags);
+ /**
+  * gpio_get_list_count() - Returns the number of GPIOs in a list
+  *
+  * Counts the GPIOs in a list. See gpio_request_by_name() for additional
+  * details.
+  *
+  * @dev:      Device requesting the GPIO
+  * @list_name:        Name of GPIO list (e.g. "board-id-gpios")
+  * @return number of GPIOs (0 for an empty property) or -ENOENT if the list
+  * does not exist
+  */
+ int gpio_get_list_count(struct udevice *dev, const char *list_name);
+ /**
+  * gpio_request_by_name_nodev() - request GPIOs without a device
+  *
+  * This is a version of gpio_request_list_by_name() that does not use a
+  * device. Avoid it unless the caller is not yet using driver model
+  */
+ int gpio_request_by_name_nodev(const void *blob, int node,
+                              const char *list_name,
+                              int index, struct gpio_desc *desc, int flags);
+ /**
+  * gpio_request_list_by_name_nodev() - request GPIOs without a device
+  *
+  * This is a version of gpio_request_list_by_name() that does not use a
+  * device. Avoid it unless the caller is not yet using driver model
+  */
+ int gpio_request_list_by_name_nodev(const void *blob, int node,
+                                   const char *list_name,
+                                   struct gpio_desc *desc_list, int max_count,
+                                   int flags);
+ /**
+  * dm_gpio_free() - Free a single GPIO
+  *
+  * This frees a single GPIOs previously returned from gpio_request_by_name().
+  *
+  * @dev:      Device which requested the GPIO
+  * @desc:     GPIO to free
+  * @return 0 if OK, -ve on error
+  */
+ int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc);
+ /**
+  * gpio_free_list() - Free a list of GPIOs
+  *
+  * This frees a list of GPIOs previously returned from
+  * gpio_request_list_by_name().
+  *
+  * @dev:      Device which requested the GPIOs
+  * @desc:     List of GPIOs to free
+  * @count:    Number of GPIOs in the list
+  * @return 0 if OK, -ve on error
+  */
+ int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count);
+ /**
+  * gpio_free_list_nodev() - free GPIOs without a device
+  *
+  * This is a version of gpio_free_list() that does not use a
+  * device. Avoid it unless the caller is not yet using driver model
+  */
+ int gpio_free_list_nodev(struct gpio_desc *desc, int count);
+ /**
+  * dm_gpio_get_value() - Get the value of a GPIO
+  *
+  * This is the driver model version of the existing gpio_get_value() function
+  * and should be used instead of that.
+  *
+  * For now, these functions have a dm_ prefix since they conflict with
+  * existing names.
+  *
+  * @desc:     GPIO description containing device, offset and flags,
+  *            previously returned by gpio_request_by_name()
+  * @return GPIO value (0 for inactive, 1 for active) or -ve on error
+  */
+ int dm_gpio_get_value(struct gpio_desc *desc);
+ int dm_gpio_set_value(struct gpio_desc *desc, int value);
+ /**
+  * dm_gpio_set_dir() - Set the direction for a GPIO
+  *
+  * This sets up the direction according tot the provided flags. It will do
+  * nothing unless the direction is actually specified.
+  *
+  * @desc:     GPIO description containing device, offset and flags,
+  *            previously returned by gpio_request_by_name()
+  * @return 0 if OK, -ve on error
+  */
+ int dm_gpio_set_dir(struct gpio_desc *desc);
+ /**
+  * dm_gpio_set_dir_flags() - Set direction using specific flags
+  *
+  * This is like dm_gpio_set_dir() except that the flags value is provided
+  * instead of being used from desc->flags. This is needed because in many
+  * cases the GPIO description does not include direction information.
+  * Note that desc->flags is updated by this function.
+  *
+  * @desc:     GPIO description containing device, offset and flags,
+  *            previously returned by gpio_request_by_name()
+  * @flags:    New flags to use
+  * @return 0 if OK, -ve on error, in which case desc->flags is not updated
+  */
+ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
+ /**
+  * gpio_get_number() - Get the global GPIO number of a GPIO
+  *
+  * This should only be used for debugging or interest. It returns the nummber
+  * that should be used for gpio_get_value() etc. to access this GPIO.
+  *
+  * @desc:     GPIO description containing device, offset and flags,
+  *            previously returned by gpio_request_by_name()
+  * @return GPIO number, or -ve if not found
+  */
+ int gpio_get_number(struct gpio_desc *desc);
  #endif        /* _ASM_GENERIC_GPIO_H_ */
diff --combined include/configs/tx53.h
index 3f1cd67128327cb9164f6b359dee9db6466777a6,0000000000000000000000000000000000000000..96d82a2ed4d5447f8d70b158b5ddc331312cf801
mode 100644,000000..100644
--- /dev/null
@@@ -1,259 -1,0 +1,256 @@@
- #ifdef CONFIG_CMD_MMC
- #ifndef CONFIG_ENV_IS_IN_NAND
- #endif
 +/*
 + * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
 + *
 + * SPDX-License-Identifier:      GPL-2.0
 + *
 + */
 +
 +#ifndef __CONFIG_H
 +#define __CONFIG_H
 +
 +#include <linux/sizes.h>
 +#include <asm/arch/imx-regs.h>
 +
 +/*
 + * Ka-Ro TX53 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
 +
 +/* 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 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
 +
 +/*
 + * Flattened Device Tree (FDT) support
 +*/
 +
 +/*
 + * 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
 +#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
 +
 +/*
 + * U-Boot Commands
 + */
 +#include <config_cmd_default.h>
 +
 +/*
 + * 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
 + */
 +#ifdef CONFIG_FEC_MXC
 +#define IMX_FEC_BASE                  FEC_BASE_ADDR
 +#define CONFIG_FEC_XCV_TYPE           MII100
 +#define CONFIG_CMD_MII
 +/* 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_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_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_MAX_CHIPS     0x1
 +#define CONFIG_SYS_MAX_NAND_DEVICE    0x1
 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE
 +#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
 +#endif /* CONFIG_CMD_NAND */
 +
 +/*
 + * MMC Driver
 + */
- #define CONFIG_DOS_PARTITION
++#ifdef CONFIG_FSL_ESDHC
 +#define CONFIG_SYS_FSL_ESDHC_ADDR     0
 +
 +#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/lcd.h
index 032308a657c91c5c265ec044029a271878350ab0,160f940d2a6698f6538e084a4322679d69855ae0..eb1d12871fced64adbd09991f8324a369c15a7db
@@@ -1,6 -1,4 +1,6 @@@
  /*
 + * Copyright (C) 2004-2010 Freescale Semiconductor, Inc.
 + *
   * MPC823 and PXA LCD Controller
   *
   * Modeled after video interface by Paolo Scaffardi
@@@ -14,6 -12,7 +14,7 @@@
  
  #ifndef _LCD_H_
  #define _LCD_H_
+ #include <lcd_console.h>
  
  extern char lcd_is_enabled;
  
@@@ -258,9 -257,6 +259,9 @@@ 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, ...);
@@@ -295,6 -291,20 +296,20 @@@ int lcd_get_screen_rows(void)
   */
  int lcd_get_screen_columns(void);
  
+ /**
+  * Get the background color of the LCD
+  *
+  * @return background color value
+  */
+ int lcd_getbgcolor(void);
+ /**
+  * Get the foreground color of the LCD
+  *
+  * @return foreground color value
+  */
+ int lcd_getfgcolor(void);
  /**
   * Set the position of the text cursor
   *
@@@ -364,15 -374,7 +379,7 @@@ void lcd_sync(void)
  /************************************************************************/
  /* ** CONSOLE CONSTANTS                                                       */
  /************************************************************************/
- #if LCD_BPP == LCD_MONOCHROME
- /*
-  * Simple black/white definitions
-  */
- # define CONSOLE_COLOR_BLACK  0
- # define CONSOLE_COLOR_WHITE  1       /* Must remain last / highest   */
- #elif LCD_BPP == LCD_COLOR8
+ #if LCD_BPP == LCD_COLOR8
  
  /*
   * 8bpp color definitions
  # define CONSOLE_COLOR_WHITE  0x00ffffff      /* Must remain last / highest*/
  # define NBYTES(bit_code)     (NBITS(bit_code) >> 3)
  
 -#else
 +#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   */
  
 +#else
 +#error Invalid LCD_BPP setting
  #endif /* color definitions */
  
  /************************************************************************/
diff --combined include/net.h
index 0dd721604fd3d6f4eb70bf2c866c7895ecb76ef9,73ea88b42d7defb35ddea2da2d0ff30684c26b30..0b338ff4e63c9cff6b266a4fd9617d4fbf523efd
@@@ -81,7 -81,7 +81,7 @@@ enum eth_state_t 
  struct eth_device {
        char name[16];
        unsigned char enetaddr[6];
-       int iobase;
+       phys_addr_t iobase;
        int state;
  
        int  (*init) (struct eth_device *, bd_t *);
@@@ -420,7 -420,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 */
@@@ -482,6 -482,36 +482,36 @@@ extern void net_set_ip_header(uchar *pk
  extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
                                int sport, int len);
  
+ /**
+  * compute_ip_checksum() - Compute IP checksum
+  *
+  * @addr:     Address to check (must be 16-bit aligned)
+  * @nbytes:   Number of bytes to check (normally a multiple of 2)
+  * @return 16-bit IP checksum
+  */
+ unsigned compute_ip_checksum(const void *addr, unsigned nbytes);
+ /**
+  * add_ip_checksums() - add two IP checksums
+  *
+  * @offset:   Offset of first sum (if odd we do a byte-swap)
+  * @sum:      First checksum
+  * @new_sum:  New checksum to add
+  * @return updated 16-bit IP checksum
+  */
+ unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);
+ /**
+  * ip_checksum_ok() - check if a checksum is correct
+  *
+  * This works by making sure the checksum sums to 0
+  *
+  * @addr:     Address to check (must be 16-bit aligned)
+  * @nbytes:   Number of bytes to check (normally a multiple of 2)
+  * @return true if the checksum matches, false if not
+  */
+ int ip_checksum_ok(const void *addr, unsigned nbytes);
  /* Checksum */
  extern int    NetCksumOk(uchar *, int);       /* Return true if cksum OK */
  extern uint   NetCksum(uchar *, int);         /* Calculate the checksum */
@@@ -556,9 -586,6 +586,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
diff --combined include/netdev.h
index c3d3d6984a242e733da6d24ddbf8cb3ff389e285,daffc1222d60afba54d8ad9dc5dba7d84d284fe0..c67b0646e4f29aa850d5b8f28eebc73e3f2d90d4
@@@ -93,7 -93,8 +93,8 @@@ int xilinx_emaclite_initialize(bd_t *bi
  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);
+ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr,
+                       int phy_addr, u32 emio);
  /*
   * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
   * exported by a public hader file, we need a global definition at this point.
@@@ -216,40 -217,4 +217,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 net/Makefile
index d7f4e65f18fcbc94bb1f4aff33a19a0b58342b6e,e9cc8ada96a783ae18444c9f68a107bede6e0054..6ba8f7575e2132729d5784ebb7cbbdc919fd5b90
@@@ -7,8 -7,8 +7,9 @@@
  
  #ccflags-y += -DDEBUG
  
+ obj-y += checksum.o
  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
diff --combined tools/Makefile
index 06719ac817464c8e1e497b5f0908af96874f73b6,6e1ce79f2f45cd33cc3e99ca278a330adb0f75bd..75ab70563a59fd1c4f1bfac240626afa932d5593
@@@ -52,7 -52,7 +52,7 @@@ HOSTCFLAGS_xway-swap-bytes.o := -pedant
  hostprogs-y += mkenvimage
  mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
  
 -hostprogs-y += dumpimage mkimage
 +#hostprogs-y += dumpimage mkimage
  hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
  
  FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
@@@ -60,7 -60,8 +60,8 @@@
  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)
+                                       rsa-sign.o rsa-verify.o rsa-checksum.o \
+                                       rsa-mod-exp.o)
  
  # common objs for dumpimage and mkimage
  dumpimage-mkimage-objs := aisimage.o \
@@@ -90,6 -91,7 +91,7 @@@
                        socfpgaimage.o \
                        lib/sha1.o \
                        lib/sha256.o \
+                       common/hash.o \
                        ublimage.o \
                        $(LIBFDT_OBJS) \
                        $(RSA_OBJS-y)
@@@ -122,6 -124,8 +124,8 @@@ HOSTLOADLIBES_dumpimage := $(HOSTLOADLI
  HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
  HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage)
  
+ HOSTLDFLAGS += -T $(srctree)/tools/imagetool.lds
  hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
  hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
  HOSTCFLAGS_mkexynosspl.o := -pedantic
@@@ -201,8 -205,6 +205,8 @@@ HOST_EXTRACFLAGS += -include $(srctree)
                $(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 \