Merge remote-tracking branch 'remotes/tx6/tx6' into karo-tx-uboot
authorLothar Waßmann <LW@KARO-electronics.de>
Fri, 21 Aug 2015 14:51:29 +0000 (16:51 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 21 Aug 2015 14:51:29 +0000 (16:51 +0200)
36 files changed:
arch/arm/cpu/armv7/mx6/hab.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/include/asm/arch-mx6/crm_regs.h
arch/arm/include/asm/arch-mx6/hab.h
arch/arm/include/asm/arch-mx6/imx-regs.h
board/karo/tx6/Kconfig
board/karo/tx6/config.mk
board/karo/tx6/flash.c
board/karo/tx6/lowlevel_init.S
board/karo/tx6/ltc3676.c
board/karo/tx6/pmic.c
board/karo/tx6/pmic.h
board/karo/tx6/rn5t567.c
board/karo/tx6/rn5t618.c
board/karo/tx6/tx6qdl.c
board/karo/tx6/u-boot.lds
common/Kconfig
common/cmd_fuse.c
common/cmd_mmc.c
configs/tx6q-1020_defconfig
configs/tx6q-1020_mfg_defconfig
configs/tx6q-1020_noenv_defconfig
configs/tx6q-1020_sec_defconfig [new file with mode: 0644]
configs/tx6q-10x0_sec_defconfig [new file with mode: 0644]
configs/tx6s-8034_defconfig
configs/tx6s-8034_mfg_defconfig
configs/tx6s-8034_noenv_defconfig
configs/tx6s-8034_sec_defconfig [new file with mode: 0644]
configs/tx6u-8012_sec_defconfig [new file with mode: 0644]
configs/tx6u-8033_sec_defconfig [new file with mode: 0644]
configs/tx6u-80x0_sec_defconfig [new file with mode: 0644]
drivers/misc/mxc_ocotp.c
drivers/mmc/mmc.c
drivers/mtd/nand/mxs_nand.c
include/configs/tx6.h
include/mmc.h

index 8dee595..757096d 100644 (file)
@@ -3,78 +3,42 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
-
 #include <common.h>
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/arch/hab.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/hab.h>
 
-/* -------- start of HAB API updates ------------*/
-
-#define hab_rvt_report_event_p                                 \
-(                                                              \
-       ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
-         is_cpu_type(MXC_CPU_MX6D)) &&                         \
-         (soc_rev() >= CHIP_REV_1_5)) ?                        \
-       ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) :  \
-       (is_cpu_type(MXC_CPU_MX6DL) &&                          \
-        (soc_rev() >= CHIP_REV_1_2)) ?                         \
-       ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) :  \
-       ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)        \
-)
-
-#define hab_rvt_report_status_p                                        \
-(                                                              \
-       ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
-         is_cpu_type(MXC_CPU_MX6D)) &&                         \
-         (soc_rev() >= CHIP_REV_1_5)) ?                        \
-       ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
-       (is_cpu_type(MXC_CPU_MX6DL) &&                          \
-        (soc_rev() >= CHIP_REV_1_2)) ?                         \
-       ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
-       ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)      \
-)
-
-#define hab_rvt_authenticate_image_p                           \
-(                                                              \
-       ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
-         is_cpu_type(MXC_CPU_MX6D)) &&                         \
-         (soc_rev() >= CHIP_REV_1_5)) ?                        \
-       ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
-       (is_cpu_type(MXC_CPU_MX6DL) &&                          \
-        (soc_rev() >= CHIP_REV_1_2)) ?                         \
-       ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
-       ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)    \
-)
-
-#define hab_rvt_entry_p                                                \
-(                                                              \
-       ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
-         is_cpu_type(MXC_CPU_MX6D)) &&                         \
-         (soc_rev() >= CHIP_REV_1_5)) ?                        \
-       ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) :                \
-       (is_cpu_type(MXC_CPU_MX6DL) &&                          \
-        (soc_rev() >= CHIP_REV_1_2)) ?                         \
-       ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) :                \
-       ((hab_rvt_entry_t *)HAB_RVT_ENTRY)                      \
-)
-
-#define hab_rvt_exit_p                                         \
-(                                                              \
-       ((is_cpu_type(MXC_CPU_MX6Q) ||                          \
-         is_cpu_type(MXC_CPU_MX6D)) &&                         \
-         (soc_rev() >= CHIP_REV_1_5)) ?                        \
-       ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) :                  \
-       (is_cpu_type(MXC_CPU_MX6DL) &&                          \
-        (soc_rev() >= CHIP_REV_1_2)) ?                         \
-       ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) :                  \
-       ((hab_rvt_exit_t *)HAB_RVT_EXIT)                        \
-)
+HAB_FUNC(entry, hab_status_t)
+HAB_FUNC(exit, hab_status_t)
+HAB_FUNC5(authenticate_image, void *, uint8_t, size_t, void **, size_t *, hab_loader_callback_f_t)
+//HAB_FUNC1(run_dcd, hab_status_t, const uint8_t *)
+HAB_FUNC2(run_csf, hab_status_t, const uint8_t *, uint8_t)
+HAB_FUNC2(report_status, hab_status_t, hab_config_t *, hab_state_t *)
+HAB_FUNC4(report_event, hab_status_t, hab_status_t, uint32_t, uint8_t *, size_t *)
+HAB_FUNC3(check_target, hab_status_t, uint8_t, const void *, size_t)
+HAB_FUNC3(assert, hab_status_t, uint8_t, const void *, size_t)
+
+struct mx6_ivt {
+       u32 header;
+       u32 entry;
+       u32 rsrvd1;
+       void *dcd;
+       struct mx6_boot_data *boot_data;
+       void *self;
+       void *csf;
+       u32 rsrvd2;
+};
+
+struct mx6_boot_data {
+       void *start;
+       u32 length;
+       u32 plugin;
+};
 
 #define IVT_SIZE               0x20
-#define ALIGN_SIZE             0x1000
+#define ALIGN_SIZE             0x400
 #define CSF_PAD_SIZE           0x2000
 #define MX6DQ_PU_IROM_MMU_EN_VAR       0x009024a8
 #define MX6DLS_PU_IROM_MMU_EN_VAR      0x00901dd0
  * +------------+ + CSF_PAD_SIZE
  */
 
-bool is_hab_enabled(void)
+static bool is_hab_enabled(void)
 {
        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
        struct fuse_bank *bank = &ocotp->bank[0];
        struct fuse_bank0_regs *fuse =
                (struct fuse_bank0_regs *)bank->fuse_regs;
        uint32_t reg = readl(&fuse->cfg5);
-
+       static int first = 1;
+
+       if (first) {
+               debug("rvt_base=%p\n", hab_rvt_base());
+               debug("hab_rvt_entry=%p\n", hab_rvt_entry_p);
+               debug("hab_rvt_exit=%p\n", hab_rvt_exit_p);
+               debug("hab_rvt_check_target=%p\n", hab_rvt_check_target_p);
+               debug("hab_rvt_authenticate_image=%p\n", hab_rvt_authenticate_image_p);
+               debug("hab_rvt_report_event=%p\n", hab_rvt_report_event_p);
+               debug("hab_rvt_report_status=%p\n", hab_rvt_report_status_p);
+               debug("hab_rvt_assert=%p\n", hab_rvt_assert_p);
+               first = 0;
+       }
        return (reg & 0x2) == 0x2;
 }
 
-void display_event(uint8_t *event_data, size_t bytes)
+static void display_event(uint8_t *event_data, size_t bytes)
 {
        uint32_t i;
 
@@ -141,29 +117,27 @@ void display_event(uint8_t *event_data, size_t bytes)
 
 int get_hab_status(void)
 {
-       uint32_t index = 0; /* Loop index */
+       static uint32_t last_hab_event __attribute__((section(".data")));
+       uint32_t index = last_hab_event; /* Loop index */
        uint8_t event_data[128]; /* Event data buffer */
        size_t bytes = sizeof(event_data); /* Event size in bytes */
-       enum hab_config config = 0;
-       enum hab_state state = 0;
-       hab_rvt_report_event_t *hab_rvt_report_event;
-       hab_rvt_report_status_t *hab_rvt_report_status;
-
-       hab_rvt_report_event = hab_rvt_report_event_p;
-       hab_rvt_report_status = hab_rvt_report_status_p;
+       enum hab_config config;
+       enum hab_state state;
+       int ret;
 
        if (is_hab_enabled())
-               puts("\nSecure boot enabled\n");
+               puts("Secure boot enabled\n");
        else
-               puts("\nSecure boot disabled\n");
+               puts("Secure boot disabled\n");
 
        /* Check HAB status */
-       if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
-               printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
-                      config, state);
-
+       config = state = 0; /* ROM code assumes short enums! */
+       ret = hab_rvt_report_status(&config, &state);
+       printf("HAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+               config, state);
+       if (ret != HAB_SUCCESS) {
                /* Display HAB Error events */
-               while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
+               while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
                                        &bytes) == HAB_SUCCESS) {
                        puts("\n");
                        printf("--------- HAB Event %d -----------------\n",
@@ -174,145 +148,161 @@ int get_hab_status(void)
                        bytes = sizeof(event_data);
                        index++;
                }
+               ret = index - last_hab_event;
+               last_hab_event = index;
+       } else {
+               /* Display message if no HAB events are found */
+               puts("No HAB Events Found!\n");
+               ret = 0;
        }
-       /* Display message if no HAB events are found */
-       else {
-               printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
-                      config, state);
-               puts("No HAB Events Found!\n\n");
-       }
-       return 0;
+       return ret;
 }
 
-uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
+static inline hab_status_t hab_init(void)
 {
-       uint32_t load_addr = 0;
-       size_t bytes;
-       ptrdiff_t ivt_offset = 0;
-       int result = 0;
-       ulong start;
-       hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
-       hab_rvt_entry_t *hab_rvt_entry;
-       hab_rvt_exit_t *hab_rvt_exit;
-
-       hab_rvt_authenticate_image = hab_rvt_authenticate_image_p;
-       hab_rvt_entry = hab_rvt_entry_p;
-       hab_rvt_exit = hab_rvt_exit_p;
-
-       if (is_hab_enabled()) {
-               printf("\nAuthenticate image from DDR location 0x%x...\n",
-                      ddr_start);
-
-               hab_caam_clock_enable(1);
-
-               if (hab_rvt_entry() == HAB_SUCCESS) {
-                       /* If not already aligned, Align to ALIGN_SIZE */
-                       ivt_offset = (image_size + ALIGN_SIZE - 1) &
-                                       ~(ALIGN_SIZE - 1);
-
-                       start = ddr_start;
-                       bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
-#ifdef DEBUG
-                       printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n",
-                              ivt_offset, ddr_start + ivt_offset);
-                       puts("Dumping IVT\n");
-                       print_buffer(ddr_start + ivt_offset,
-                                    (void *)(ddr_start + ivt_offset),
-                                    4, 0x8, 0);
-
-                       puts("Dumping CSF Header\n");
-                       print_buffer(ddr_start + ivt_offset+IVT_SIZE,
-                                    (void *)(ddr_start + ivt_offset+IVT_SIZE),
-                                    4, 0x10, 0);
-
-                       get_hab_status();
-
-                       puts("\nCalling authenticate_image in ROM\n");
-                       printf("\tivt_offset = 0x%x\n", ivt_offset);
-                       printf("\tstart = 0x%08lx\n", start);
-                       printf("\tbytes = 0x%x\n", bytes);
-#endif
-                       /*
-                        * If the MMU is enabled, we have to notify the ROM
-                        * code, or it won't flush the caches when needed.
-                        * This is done, by setting the "pu_irom_mmu_enabled"
-                        * word to 1. You can find its address by looking in
-                        * the ROM map. This is critical for
-                        * authenticate_image(). If MMU is enabled, without
-                        * setting this bit, authentication will fail and may
-                        * crash.
-                        */
-                       /* Check MMU enabled */
-                       if (get_cr() & CR_M) {
-                               if (is_cpu_type(MXC_CPU_MX6Q) ||
-                                   is_cpu_type(MXC_CPU_MX6D)) {
-                                       /*
-                                        * This won't work on Rev 1.0.0 of
-                                        * i.MX6Q/D, since their ROM doesn't
-                                        * do cache flushes. don't think any
-                                        * exist, so we ignore them.
-                                        */
-                                       writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
-                               } else if (is_cpu_type(MXC_CPU_MX6DL) ||
-                                          is_cpu_type(MXC_CPU_MX6SOLO)) {
-                                       writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
-                               } else if (is_cpu_type(MXC_CPU_MX6SL)) {
-                                       writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
-                               }
-                       }
-
-                       load_addr = (uint32_t)hab_rvt_authenticate_image(
-                                       HAB_CID_UBOOT,
-                                       ivt_offset, (void **)&start,
-                                       (size_t *)&bytes, NULL);
-                       if (hab_rvt_exit() != HAB_SUCCESS) {
-                               puts("hab exit function fail\n");
-                               load_addr = 0;
-                       }
-               } else {
-                       puts("hab entry function fail\n");
-               }
+       hab_status_t ret;
 
-               hab_caam_clock_enable(0);
-
-               get_hab_status();
-       } else {
+       if (!is_hab_enabled()) {
                puts("hab fuse not enabled\n");
+               return HAB_FAILURE;
        }
 
-       if ((!is_hab_enabled()) || (load_addr != 0))
-               result = 1;
+       hab_caam_clock_enable(1);
 
-       return result;
+       ret = hab_rvt_entry();
+       debug("hab_rvt_entry() returned %02x\n", ret);
+       if (ret != HAB_SUCCESS) {
+               printf("hab entry function failed: %02x\n", ret);
+               hab_caam_clock_enable(0);
+       }
+
+       return ret;
 }
 
-int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static inline hab_status_t hab_exit(void)
 {
-       if ((argc != 1)) {
-               cmd_usage(cmdtp);
-               return 1;
+       hab_status_t ret;
+
+       ret = hab_rvt_exit();
+       if (ret != HAB_SUCCESS)
+               printf("hab exit function failed: %02x\n", ret);
+
+       hab_caam_clock_enable(0);
+
+       return ret;
+}
+
+static hab_status_t hab_check_target(hab_target_t type, uint32_t addr, size_t len)
+{
+       hab_status_t ret;
+
+       ret = hab_init();
+       if (ret != HAB_SUCCESS)
+               return ret;
+
+       ret = hab_rvt_check_target(type, (void *)addr, len);
+       if (ret != HAB_SUCCESS) {
+               printf("check_target(0x%08x, 0x%08x) failed: %d\n",
+                       addr, len, ret);
+               return ret;
        }
+       ret = hab_exit();
+
+       if (ret == HAB_SUCCESS && get_hab_status() > 0) {
+               return HAB_FAILURE;
+       }
+       return ret;
+}
+
+static hab_status_t hab_assert(uint32_t type, uint32_t addr, size_t len)
+{
+       hab_status_t ret;
+
+       ret = hab_init();
+       if (ret != HAB_SUCCESS)
+               return ret;
+
+       ret = hab_rvt_assert(type, (void *)addr, len);
+       if (ret != HAB_SUCCESS) {
+               printf("assert(0x%08x, 0x%08x) failed: %d\n",
+                       addr, len, ret);
+               return ret;
+       }
+       ret = hab_exit();
+
+       if (ret == HAB_SUCCESS && get_hab_status() > 0) {
+               return HAB_FAILURE;
+       }
+       return ret;
+}
+
+static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
+                       char *const argv[])
+{
+       if (argc != 1)
+               return CMD_RET_USAGE;
 
        get_hab_status();
 
-       return 0;
+       return CMD_RET_SUCCESS;
+}
+
+static int do_hab_check_target(cmd_tbl_t *cmdtp, int flag, int argc,
+                       char *const argv[])
+{
+       hab_target_t type = HAB_TGT_ANY;
+       uint32_t addr;
+       size_t len;
+
+       if (argc < 3)
+               return CMD_RET_USAGE;
+
+       addr = simple_strtoul(argv[1], NULL, 16);
+       len = simple_strtoul(argv[2], NULL, 16);
+       if (argc > 3) {
+               switch (argv[3][0]) {
+               case 'p':
+               case 'P':
+                       type = HAB_TGT_PERIPHERAL;
+                       break;
+               case 'm':
+               case 'M':
+                       type = HAB_TGT_MEMORY;
+                       break;
+               case 'a':
+               case 'A':
+                       break;
+               default:
+                       printf("Invalid type '%s'\n", argv[3]);
+                       return CMD_RET_USAGE;
+               }
+       }
+       if (hab_check_target(type, addr, len) != HAB_SUCCESS)
+               return CMD_RET_FAILURE;
+
+       return CMD_RET_SUCCESS;
 }
 
-static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
-                               char * const argv[])
+static int do_hab_assert(cmd_tbl_t *cmdtp, int flag, int argc,
+                       char *const argv[])
 {
-       ulong   addr, ivt_offset;
-       int     rcode = 0;
+       uint32_t type = 0;
+       uint32_t addr;
+       size_t len;
 
        if (argc < 3)
                return CMD_RET_USAGE;
 
        addr = simple_strtoul(argv[1], NULL, 16);
-       ivt_offset = simple_strtoul(argv[2], NULL, 16);
+       len = simple_strtoul(argv[2], NULL, 16);
+       if (argc > 3) {
+               type = simple_strtoul(argv[3], NULL, 16);
+       }
 
-       rcode = authenticate_image(addr, ivt_offset);
+       if (hab_assert(type, addr, len) != HAB_SUCCESS)
+               return CMD_RET_FAILURE;
 
-       return rcode;
+       return CMD_RET_SUCCESS;
 }
 
 U_BOOT_CMD(
@@ -322,9 +312,17 @@ U_BOOT_CMD(
          );
 
 U_BOOT_CMD(
-               hab_auth_img, 3, 0, do_authenticate_image,
-               "authenticate image via HAB",
-               "addr ivt_offset\n"
-               "addr - image hex address\n"
-               "ivt_offset - hex offset of IVT in the image"
+               hab_check_target, 4, 0, do_hab_check_target,
+               "verify an address range via HAB",
+               "addr len [type]\n"
+               "\t\taddr -\taddress to verify\n"
+               "\t\tlen -\tlength of addr range to verify\n"
+         );
+
+U_BOOT_CMD(
+               hab_assert, 4, 0, do_hab_assert,
+               "Test an assertion against the HAB audit log",
+               "addr len [type]\n"
+               "\t\taddr -\taddress to verify\n"
+               "\t\tlen -\tlength of addr range to verify\n"
          );
index 223cdc2..63d50c1 100644 (file)
@@ -8,6 +8,11 @@
  */
 
 #include <common.h>
+#include <stdbool.h>
+#include <dm.h>
+#include <div64.h>
+#include <ipu.h>
+#include <imx_thermal.h>
 #include <asm/armv7.h>
 #include <asm/bootm.h>
 #include <asm/pl310.h>
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/regs-ocotp.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/mxc_hdmi.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/dma.h>
-#include <stdbool.h>
-#include <asm/arch/mxc_hdmi.h>
-#include <asm/arch/crm_regs.h>
-#include <asm/bootm.h>
-#include <dm.h>
-#include <imx_thermal.h>
-#include <div64.h>
-#include <ipu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
index 261a7b3..ce465c6 100644 (file)
@@ -318,13 +318,13 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CHSCCDR_M4_CLK_SEL_MASK                        (0x7 << MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET              0
 #else
-#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_DI1_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET    15
 #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK             (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET           12
 #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK          (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET                9
-#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_DI0_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET    6
 #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK             (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET           3
@@ -332,18 +332,22 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET                0
 #endif
 
+#define CHSCCDR_CLK_SEL_LDB_DI0                                3
+#define CHSCCDR_PODF_DIVIDE_BY_3                       2
+#define CHSCCDR_IPU_PRE_CLK_540M_PFD                   5
+
 /* Define the bits in register CSCDR2 */
 #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK             (0x3F << MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET)
 #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET           19
 /* All IPU2_DI1 are LCDIF1 on MX6SX */
-#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_DI1_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET     15
 #define MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK              (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET)
 #define MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET            12
 #define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK           (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET         9
 /* All IPU2_DI0 are LCDIF2 on MX6SX */
-#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_DI0_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET     6
 #define MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK              (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET)
 #define MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET            3
index 230be45..e856516 100644 (file)
@@ -5,31 +5,36 @@
  *
 */
 
-#ifndef __SECURE_MX6Q_H__
-#define __SECURE_MX6Q_H__
+#ifndef __ARCH_MX6_HAB_H
+#define __ARCH_MX6_HAB_H
+
+#ifdef CONFIG_SECURE_BOOT
 
 #include <linux/types.h>
+#include <asm/arch/sys_proto.h>
+
+int get_hab_status(void);
 
 /* -------- start of HAB API updates ------------*/
 /* The following are taken from HAB4 SIS */
 
 /* Status definitions */
-enum hab_status {
+typedef enum hab_status {
        HAB_STS_ANY = 0x00,
        HAB_FAILURE = 0x33,
        HAB_WARNING = 0x69,
        HAB_SUCCESS = 0xf0
-};
+} hab_status_t;
 
 /* Security Configuration definitions */
-enum hab_config {
+typedef enum hab_config {
        HAB_CFG_RETURN = 0x33, /**< Field Return IC */
        HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */
        HAB_CFG_CLOSED = 0xcc /**< Secure IC */
-};
+} hab_config_t;
 
 /* State definitions */
-enum hab_state {
+typedef enum hab_state {
        HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */
        HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */
        HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */
@@ -39,18 +44,53 @@ enum hab_state {
        HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */
        HAB_STATE_NONE = 0xf0, /**< No security state machine */
        HAB_STATE_MAX
+} hab_state_t;
+
+typedef enum hab_target {
+       HAB_TGT_MEMORY = 0x0f, /* Check memory white list */
+       HAB_TGT_PERIPHERAL = 0xf0, /* Check peripheral white list*/
+       HAB_TGT_ANY = 0x55, /**< Check memory & peripheral white list */
+} hab_target_t;
+
+enum HAB_FUNC_OFFSETS {
+       HAB_RVT_HEADER,
+       HAB_RVT_ENTRY,
+       HAB_RVT_EXIT,
+       HAB_RVT_CHECK_TARGET,
+       HAB_RVT_AUTHENTICATE_IMAGE,
+       HAB_RVT_RUN_DCD,
+       HAB_RVT_RUN_CSF,
+       HAB_RVT_ASSERT,
+       HAB_RVT_REPORT_EVENT,
+       HAB_RVT_REPORT_STATUS,
+       HAB_RVT_FAILSAFE,
 };
 
-/*Function prototype description*/
-typedef enum hab_status hab_rvt_report_event_t(enum hab_status, uint32_t,
-               uint8_t* , size_t*);
-typedef enum hab_status hab_rvt_report_status_t(enum hab_config *,
-               enum hab_state *);
-typedef enum hab_status hab_loader_callback_f_t(void**, size_t*, const void*);
-typedef enum hab_status hab_rvt_entry_t(void);
-typedef enum hab_status hab_rvt_exit_t(void);
+/* Function prototype description */
+typedef hab_status_t hab_rvt_entry_t(void);
+
+typedef hab_status_t hab_rvt_exit_t(void);
+
+typedef hab_status_t hab_rvt_check_target_t(hab_target_t, const void *,
+               size_t);
+
+typedef hab_status_t hab_loader_callback_f_t(void**, size_t*, const void*);
 typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
                void **, size_t *, hab_loader_callback_f_t);
+
+typedef hab_status_t hab_rvt_run_dcd_t(const uint8_t *dcd);
+
+typedef hab_status_t hab_rvt_run_csf_t(const uint8_t *csf, uint8_t cid);
+
+typedef hab_status_t hab_rvt_assert_t(uint32_t, const void *,
+               size_t);
+
+typedef hab_status_t hab_rvt_report_event_t(hab_status_t, uint32_t,
+               uint8_t* , size_t*);
+
+typedef hab_status_t hab_rvt_report_status_t(enum hab_config *,
+               enum hab_state *);
+
 typedef void hapi_clock_init_t(void);
 
 #ifdef CONFIG_SOC_MX6SX
@@ -59,20 +99,109 @@ typedef void hapi_clock_init_t(void);
 #define HAB_RVT_BASE                   0x00000094
 #endif
 
-#define HAB_RVT_ENTRY                  (*(uint32_t *)(HAB_RVT_BASE + 0x04))
-#define HAB_RVT_EXIT                   (*(uint32_t *)(HAB_RVT_BASE + 0x08))
-#define HAB_RVT_AUTHENTICATE_IMAGE     (*(uint32_t *)(HAB_RVT_BASE + 0x10))
-#define HAB_RVT_REPORT_EVENT           (*(uint32_t *)(HAB_RVT_BASE + 0x20))
-#define HAB_RVT_REPORT_STATUS          (*(uint32_t *)(HAB_RVT_BASE + 0x24))
+static inline void **hab_rvt_base(void)
+{
+       uint32_t *base;
 
-#define HAB_RVT_REPORT_EVENT_NEW               (*(uint32_t *)0x000000B8)
-#define HAB_RVT_REPORT_STATUS_NEW              (*(uint32_t *)0x000000BC)
-#define HAB_RVT_AUTHENTICATE_IMAGE_NEW         (*(uint32_t *)0x000000A8)
-#define HAB_RVT_ENTRY_NEW                      (*(uint32_t *)0x0000009C)
-#define HAB_RVT_EXIT_NEW                       (*(uint32_t *)0x000000A0)
+       if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) &&
+               soc_rev() >= CHIP_REV_1_5) ||
+               (is_cpu_type(MXC_CPU_MX6DL) && soc_rev() >= CHIP_REV_1_2) ||
+               is_cpu_type(MXC_CPU_MX6SOLO))
+               base = (void *)0x98;
+       else
+               base = (void *)0x94;
+       if ((*base & 0xff0000ff) != cpu_to_be32(0xdd000041)) {
+               printf("Invalid RVT @ %p\n", base);
+               return NULL;
+       }
+       return (void **)base;
+}
 
 #define HAB_CID_ROM 0 /**< ROM Caller ID */
 #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
 /* ----------- end of HAB API updates ------------*/
 
-#endif
+#define hab_rvt_entry_p                                                \
+       ((hab_rvt_entry_t *)hab_rvt_base()[HAB_RVT_ENTRY])
+
+#define hab_rvt_exit_p                                         \
+       ((hab_rvt_exit_t *)hab_rvt_base()[HAB_RVT_EXIT])
+
+#define hab_rvt_check_target_p                                 \
+       ((hab_rvt_check_target_t*)hab_rvt_base()[HAB_RVT_CHECK_TARGET])
+
+#define hab_rvt_authenticate_image_p                           \
+       ((hab_rvt_authenticate_image_t *)hab_rvt_base()[HAB_RVT_AUTHENTICATE_IMAGE])
+
+#define hab_rvt_run_dcd_p                                      \
+       ((hab_rvt_run_dcd_t*)hab_rvt_base()[HAB_RVT_RUN_DCD])
+
+#define hab_rvt_run_csf_p                                      \
+       ((hab_rvt_run_csf_t*)hab_rvt_base()[HAB_RVT_RUN_CSF])
+
+#define hab_rvt_assert_p                                       \
+       ((hab_rvt_assert_t*)hab_rvt_base()[HAB_RVT_ASSERT])
+
+#define hab_rvt_report_event_p                                 \
+       ((hab_rvt_report_event_t*)hab_rvt_base()[HAB_RVT_REPORT_EVENT])
+
+#define hab_rvt_report_status_p                                        \
+       ((hab_rvt_report_status_t*)hab_rvt_base()[HAB_RVT_REPORT_STATUS])
+
+#define HAB_FUNC(n, rt)                                                        \
+static inline rt hab_rvt_##n(void)                                     \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p();                                       \
+}                                                                      \
+
+#define HAB_FUNC1(n, rt, t1)                                           \
+static inline rt hab_rvt_##n(t1 p1)                                    \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p(p1);                                     \
+}
+
+#define HAB_FUNC2(n, rt, t1, t2)                                       \
+static inline rt hab_rvt_##n(t1 p1, t2 p2)                             \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p(p1, p2);                                 \
+}
+
+#define HAB_FUNC3(n, rt, t1, t2, t3)                                   \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3)                      \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p(p1, p2, p3);                             \
+}
+
+#define HAB_FUNC4(n, rt, t1, t2, t3, t4)                               \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3, t4 p4)               \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p(p1, p2, p3, p4);                         \
+}
+
+#define HAB_FUNC5(n, rt, t1, t2, t3, t4, t5)                           \
+static inline rt hab_rvt_##n(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5)                \
+{                                                                      \
+       if (hab_rvt_base() == NULL)                                     \
+               return (rt)-1;                                          \
+       return hab_rvt_##n##_p(p1, p2, p3, p4, p5);                     \
+}
+
+#else /* CONFIG_SECURE_BOOT */
+
+static inline int get_hab_status(void)
+{
+       return 0;
+}
+
+#endif /* CONFIG_SECURE_BOOT */
+#endif /* __ARCH_MX6_HAB_H */
index bc1c58a..6fbc441 100644 (file)
@@ -591,7 +591,7 @@ struct ocotp_regs {
        reg_32(timing);
        reg_32(data);
        reg_32(read_ctrl);
-       reg_32(fuse_data);
+       reg_32(read_fuse_data);
        reg_32(sticky);
        mxs_reg_32(scs);
        reg_32(crc_addr);
index c848d59..091efde 100644 (file)
@@ -1,27 +1,5 @@
 if TARGET_TX6
 
-config MX6
-       bool
-       default y
-
-config MX6Q
-       bool
-
-config MX6DL
-       bool
-
-config MX6QDL
-       bool
-
-config MX6S
-       bool
-
-config MX6SL
-       bool
-
-config MX6SX
-       bool
-
 config SYS_BOARD
        default "tx6"
 
@@ -34,25 +12,25 @@ config SYS_SOC
 config SYS_CONFIG_NAME
        default "tx6"
 
-config CMD_ROMUPDATE
-       bool
-
 config TX6
        bool
        default y
-       select MX6
        select CMD_BMP if LCD
        select CMD_BOOTCE
        select CMD_BOOTZ
        select CMD_CACHE
        select CMD_I2C if I2C
        select CMD_MEMTEST
+       select CMD_MMC
        select CMD_TIME
        select DM
        select DM_GPIO
+       select LIB_RAND
+       select PHYLIB
        select SYS_I2C
        select SYS_I2C_MXC
        select GET_FEC_MAC_ADDR_FROM_IIM
+       select OF_BOARD_SETUP
        select OF_LIBFDT
 
 config TX6_NAND
@@ -64,8 +42,10 @@ config TX6_NAND
        select CMD_ROMUPDATE
        select FDT_FIXUP_PARTITIONS if OF_LIBFDT
        select MTD_PARTITIONS
-       select NAND_MXS_NO_BBM_SWAP if NAND_MXS
-       select SYS_NAND_USE_FLASH_BBT if NAND_MXS
+       select NAND
+       select NAND_MXS
+       select NAND_MXS_NO_BBM_SWAP
+       select SYS_NAND_USE_FLASH_BBT
        select APBH_DMA
        select APBH_DMA_BURST
        select APBH_DMA_BURST8
@@ -93,62 +73,57 @@ choice
 
 config TARGET_TX6Q_10X0
        bool "TX6Q-1010 and TX6Q-1030"
-       select MX6Q
+       select SOC_MX6Q
 
 config TARGET_TX6Q_1020
        bool "TX6Q-1020"
-       select MX6Q
+       select SOC_MX6Q
        select TX6_EMMC
-       select TX6_REV_2
 
 config TARGET_TX6Q_11X0
        bool "TX6Q-1110 and TX6Q-1130"
-       select MX6Q
+       select SOC_MX6Q
        select SYS_LVDS_IF
        
 config TARGET_TX6S_8034
        bool "TX6S-8034"
-       select MX6S
+       select SOC_MX6S
        select SYS_SDRAM_BUS_WIDTH_16
 
 config TARGET_TX6S_8035
        bool "TX6S-8035"
-       select MX6S
+       select SOC_MX6S
        select TX6_EMMC
        select SYS_SDRAM_BUS_WIDTH_32
 
-config TARGET_TX6U_8010
+config TARGET_TX6U_80X0
        bool "TX6U-8010 and TX6U-8030"
-       select MX6DL
+       select SOC_MX6DL
 
 config TARGET_TX6U_8011
        bool "TX6U-8011"
-       select MX6DL
+       select SOC_MX6DL
        select SYS_SDRAM_BUS_WIDTH_32
-       select TX6_REV_1
 
 config TARGET_TX6U_8012
        bool "TX6U-8012"
-       select MX6DL
-       select TX6_REV_1
+       select SOC_MX6DL
 
 config TARGET_TX6U_81X0
        bool "TX6U-8110 and TX6U-8130"
-       select MX6DL
+       select SOC_MX6DL
        select SYS_LVDS_IF
 
 config TARGET_TX6U_8111
        bool "TX6U-8111"
-       select MX6DL
+       select SOC_MX6DL
        select SYS_SDRAM_BUS_WIDTH_32
        select SYS_LVDS_IF
-       select TX6_REV_1
 
 config TARGET_TX6U_8033
        bool "TX6U-8033"
-       select MX6DL
+       select SOC_MX6DL
        select TX6_EMMC
-       select TX6_REV_3
 
 endchoice
 
index 9f156bc..acb0cd0 100644 (file)
@@ -1,11 +1,17 @@
 # stack is allocated below CONFIG_SYS_TEXT_BASE
-CONFIG_SYS_TEXT_BASE := 0x10100000
+#CONFIG_SYS_TEXT_BASE := 0x10100000
+#CONFIG_SYS_TEXT_BASE := 0x177ff000
+CONFIG_SYS_TEXT_BASE := 0x100ff000
+
+OBJCOPYFLAGS += -j .pad
 
-__HAVE_ARCH_GENERIC_BOARD := y
 LOGO_BMP = logos/karo.bmp
 #PLATFORM_CPPFLAGS += -DDEBUG
 #PLATFORM_CPPFLAGS += -Wno-unused-but-set-variable
 PLATFORM_CPPFLAGS += -Werror
+ifneq ($(CONFIG_SECURE_BOOT),)
+       PLATFORM_CPPFLAGS += -DCONFIG_SECURE_BOOT
+endif
 
 ifeq ($(CONFIG_TX6_NAND),y)
 # calculate U_BOOT_IMG_SIZE to be at least 3 eraseblocks larger than the maximum expected image size
index d0bb7c8..d57c994 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2012-2015 Lothar Waßmann <LW@KARO-electronics.de>
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -91,11 +91,27 @@ struct mx6_dbbt {
        u32 bb_num[2040 / 4];
 };
 
+struct mx6_ivt {
+       u32 magic;
+       u32 app_start_addr;
+       u32 rsrvd1;
+       void *dcd;
+       void *boot_data;
+       void *self;
+       void *csf;
+       u32 rsrvd2;
+};
+
+struct mx6_boot_data {
+       void *start;
+       u32 length;
+       u32 plugin;
+};
+
 #define BF_VAL(v, bf)          (((v) & bf##_MASK) >> bf##_OFFSET)
 
 static nand_info_t *mtd = &nand_info[0];
-
-extern void *_start;
+static bool doit;
 
 #define BIT(v,n)       (((v) >> (n)) & 0x1)
 
@@ -198,7 +214,8 @@ static int find_contig_space(int block, int num_blocks, int max_blocks)
        return -ENOSPC;
 }
 
-#define pr_fcb_val(p, n)       debug("%s=%08x(%d)\n", #n, (p)->n, (p)->n)
+#define offset_of(p, m)                ((void *)&(p)->m - (void *)(p))
+#define pr_fcb_val(p, n)       debug("%-24s[%02x]=%08x(%d)\n", #n, offset_of(p, n), (p)->n, (p)->n)
 
 static struct mx6_fcb *create_fcb(void *buf, int fw1_start_block,
                                int fw2_start_block, int fw_num_blocks)
@@ -327,84 +344,49 @@ static int write_fcb(void *buf, int block)
                return 0;
        }
 
-       ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
-       if (ret) {
-               printf("Failed to erase FCB block %u\n", block);
-               return ret;
+       if (doit) {
+               ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+               if (ret) {
+                       printf("Failed to erase FCB block %u\n", block);
+                       return ret;
+               }
        }
 
        printf("Writing FCB to block %d @ %08llx\n", block,
                (u64)block * mtd->erasesize);
-       chip->select_chip(mtd, 0);
-       ret = chip->write_page(mtd, chip, 0, mtd->writesize,
-                       buf, 1, page, 0, 1);
-       if (ret) {
-               printf("Failed to write FCB to block %u: %d\n", block, ret);
+       if (doit) {
+               chip->select_chip(mtd, 0);
+               ret = chip->write_page(mtd, chip, 0, mtd->writesize,
+                               buf, 1, page, 0, 1);
+               if (ret) {
+                       printf("Failed to write FCB to block %u: %d\n", block, ret);
+               }
+               chip->select_chip(mtd, -1);
        }
-       chip->select_chip(mtd, -1);
        return ret;
 }
 
-struct mx6_ivt {
-       u32 magic;
-       u32 entry;
-       u32 rsrvd1;
-       void *dcd;
-       void *boot_data;
-       void *self;
-       void *csf;
-       u32 rsrvd2;
-};
-
-struct mx6_boot_data {
-       u32 start;
-       u32 length;
-       u32 plugin;
-};
-
-static int find_ivt(void *buf)
-{
-       struct mx6_ivt *ivt_hdr = buf + 0x400;
-
-       if ((ivt_hdr->magic & 0xff0000ff) != 0x400000d1)
-               return 0;
-
-       return 1;
-}
-
-static inline void *reloc(void *dst, void *base, void *ptr)
-{
-       return dst + (ptr - base);
-}
-
-static int patch_ivt(void *buf, size_t fsize)
-{
-       struct mx6_ivt *ivt_hdr = buf + 0x400;
-       struct mx6_boot_data *boot_data;
-
-       if (!find_ivt(buf)) {
-               printf("No IVT found in image at %p\n", buf);
-               return -EINVAL;
-       }
-       boot_data = reloc(ivt_hdr, ivt_hdr->self, ivt_hdr->boot_data);
-       boot_data->length = fsize;
-
-       return 0;
-}
-
 #define chk_overlap(a,b)                               \
        ((a##_start_block <= b##_end_block &&           \
                a##_end_block >= b##_start_block) ||    \
        (b##_start_block <= a##_end_block &&            \
                b##_end_block >= a##_start_block))
 
-#define fail_if_overlap(a,b,m1,m2) do {                                \
-       if (chk_overlap(a, b)) {                                \
+#define fail_if_overlap(a,b,m1,m2) do {                                        \
+       if (!doit)                                                      \
+               printf("check: %s[%lu..%lu] <> %s[%lu..%lu]\n",         \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+       if (a##_end_block < a##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m1);       \
+       if (b##_end_block < b##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m2);       \
+       if (chk_overlap(a, b)) {                                        \
                printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
-                       m1, a##_start_block, a##_end_block,     \
-                       m2, b##_start_block, b##_end_block);    \
-               return -EINVAL;                                 \
-       }                                                       \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+               return -EINVAL;                                         \
+       }                                                               \
 } while (0)
 
 static int tx6_prog_uboot(void *addr, int start_block, int skip,
@@ -422,25 +404,28 @@ static int tx6_prog_uboot(void *addr, int start_block, int skip,
 
        printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
                erase_opts.offset + erase_opts.length - 1);
-       ret = nand_erase_opts(mtd, &erase_opts);
-       if (ret) {
-               printf("Failed to erase flash: %d\n", ret);
-               return ret;
+       if (doit) {
+               ret = nand_erase_opts(mtd, &erase_opts);
+               if (ret) {
+                       printf("Failed to erase flash: %d\n", ret);
+                       return ret;
+               }
        }
 
-       printf("Programming flash @ %08llx..%08llx from %p\n",
-               (u64)start_block * mtd->erasesize,
-               (u64)start_block * mtd->erasesize + size - 1, addr);
-       actual = size;
-       ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
-                               prg_length, addr, WITH_DROP_FFS);
-       if (ret) {
-               printf("Failed to program flash: %d\n", ret);
-               return ret;
-       }
-       if (actual < size) {
-               printf("Could only write %u of %u bytes\n", actual, size);
-               return -EIO;
+       printf("Programming flash @ %08x..%08x from %p\n",
+               prg_start, prg_start + size - 1, addr);
+       if (doit) {
+               actual = size;
+               ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                                       prg_length, addr, WITH_DROP_FFS);
+               if (ret) {
+                       printf("Failed to program flash: %d\n", ret);
+                       return ret;
+               }
+               if (actual < size) {
+                       printf("Could only write %u of %u bytes\n", actual, size);
+                       return -EIO;
+               }
        }
        return 0;
 }
@@ -458,7 +443,6 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        int ret;
        const unsigned long fcb_start_block = 0, fcb_end_block = 0;
        int erase_size = mtd->erasesize;
-       int page_size = mtd->writesize;
        void *buf;
        char *load_addr;
        char *file_size;
@@ -491,6 +475,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        if (ret)
                return ret;
 
+       doit = true;
        for (optind = 1; optind < argc; optind++) {
                char *endp;
 
@@ -543,6 +528,8 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                        mtd_num_blocks - 1);
                                return -EINVAL;
                        }
+               } else if (strcmp(argv[optind], "-n") == 0) {
+                       doit = false;
                } else if (argv[optind][0] == '-') {
                        printf("Unrecognized option %s\n", argv[optind]);
                        return -EINVAL;
@@ -559,7 +546,14 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                return -EINVAL;
        }
        if (argc - optind < 2 && file_size == NULL) {
-               printf("WARNING: Image size not specified; overwriting whole uboot partition\n");
+               if (uboot_part) {
+                       printf("WARNING: Image size not specified; overwriting whole '%s' partition\n",
+                               uboot_part);
+                       printf("This will only work, if there are no bad blocks inside this partition!\n");
+               } else {
+                       printf("ERROR: Image size must be specified\n");
+                       return -EINVAL;
+               }
        }
        if (argc > optind) {
                load_addr = NULL;
@@ -579,13 +573,10 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                size = simple_strtoul(file_size, NULL, 16);
                printf("Using default file size %08x\n", size);
        }
-       if (size > 0) {
+       if (size > 0)
                fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
-       } else {
-               fw_num_blocks = part_info->size / mtd->erasesize -
-                       extra_blocks;
-               size = fw_num_blocks * mtd->erasesize;
-       }
+       else
+               fw_num_blocks = 0;
 
        if (uboot_part) {
                ret = find_dev_and_part(uboot_part, &dev, &part_num,
@@ -597,6 +588,8 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                }
                fw1_start_block = part_info->offset / mtd->erasesize;
                max_len1 = part_info->size;
+               if (size == 0)
+                       fw_num_blocks = max_len1 / mtd->erasesize;
        } else {
                max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
        }
@@ -611,6 +604,12 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                }
                fw2_start_block = redund_part_info->offset / mtd->erasesize;
                max_len2 = redund_part_info->size;
+               if (fw2_start_block == fcb_start_block) {
+                       fw2_start_block++;
+                       max_len2 -= mtd->erasesize;
+               }
+               if (size == 0)
+                       fw_num_blocks = max_len2 / mtd->erasesize;
        } else if (fw2_set) {
                max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
        } else {
@@ -620,8 +619,9 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
                                max_len1 / mtd->erasesize);
        if (fw1_skip < 0) {
-               printf("Could not find %lu contiguous good blocks for fw image\n",
-                       fw_num_blocks);
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+                       fw_num_blocks, fw1_start_block,
+                       fw1_start_block + max_len1 / mtd->erasesize - 1);
                if (uboot_part) {
 #ifdef CONFIG_ENV_IS_IN_NAND
                        if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
@@ -639,7 +639,10 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                }
                return -ENOSPC;
        }
-       fw1_end_block = fw1_start_block + fw1_skip + fw_num_blocks - 1;
+       if (extra_blocks)
+               fw1_end_block = fw1_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw1_end_block = fw1_start_block + fw_num_blocks + fw1_skip - 1;
 
        if (fw2_set && fw2_start_block == 0)
                fw2_start_block = fw1_end_block + 1;
@@ -647,8 +650,9 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
                                        max_len2 / mtd->erasesize);
                if (fw2_skip < 0) {
-                       printf("Could not find %lu contiguous good blocks for redundant fw image\n",
-                               fw_num_blocks);
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                               fw_num_blocks, fw2_start_block,
+                               fw2_start_block + max_len2 / mtd->erasesize - 1);
                        if (redund_part) {
                                printf("Increase the size of the '%s' partition or use a different partition\n",
                                        redund_part);
@@ -660,7 +664,10 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        } else {
                fw2_skip = 0;
        }
-       fw2_end_block = fw2_start_block + fw2_skip + fw_num_blocks - 1;
+       if (extra_blocks)
+               fw2_end_block = fw2_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw2_end_block = fw2_start_block + fw_num_blocks + fw2_skip - 1;
 
 #ifdef CONFIG_ENV_IS_IN_NAND
        fail_if_overlap(fcb, env, "FCB", "Environment");
@@ -674,53 +681,44 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 #endif
                fail_if_overlap(fw1, fw2, "FW1", "FW2");
        }
+       fw1_start_block += fw1_skip;
+       fw2_start_block += fw2_skip;
 
-       buf = malloc(erase_size);
+       buf = memalign(SZ_128K, erase_size);
        if (buf == NULL) {
                printf("Failed to allocate buffer\n");
                return -ENOMEM;
        }
 
-       fcb = create_fcb(buf, fw1_start_block + fw1_skip,
-                       fw2_start_block + fw2_skip, fw_num_blocks);
+       fcb = create_fcb(buf, fw1_start_block,
+                       fw2_start_block, fw_num_blocks);
        if (IS_ERR(fcb)) {
                printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
-               free(buf);
-               return PTR_ERR(fcb);
+               ret = PTR_ERR(fcb);
+               goto out;
        }
        encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
 
        ret = write_fcb(buf, fcb_start_block);
-       free(buf);
        if (ret) {
                printf("Failed to write FCB to block %lu\n", fcb_start_block);
                return ret;
        }
-       ret = patch_ivt(addr, size);
-       if (ret) {
-               return ret;
-       }
-
-       if (size & (page_size - 1)) {
-               memset(addr + size, 0xff, size & (page_size - 1));
-               size = ALIGN(size, page_size);
-       }
 
        printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
-               addr, fw1_start_block + fw1_skip,
-               (u64)(fw1_start_block + fw1_skip) * mtd->erasesize);
+               buf, fw1_start_block, (u64)fw1_start_block * mtd->erasesize);
        ret = tx6_prog_uboot(addr, fw1_start_block, fw1_skip, size,
                        max_len1);
 
-       if (fw2_start_block == 0) {
-               return ret;
-       }
+       if (ret || fw2_start_block == 0)
+               goto out;
 
        printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
-               fw2_start_block + fw2_skip,
-               (u64)(fw2_start_block + fw2_skip) * mtd->erasesize);
-       ret = tx6_prog_uboot(addr, fw2_start_block, fw2_skip, fw_num_blocks,
+               fw2_start_block, (u64)fw2_start_block * mtd->erasesize);
+       ret = tx6_prog_uboot(addr, fw2_start_block, fw2_skip, size,
                        max_len2);
+out:
+       free(buf);
        return ret;
 }
 
@@ -728,12 +726,13 @@ U_BOOT_CMD(romupdate, 11, 0, do_update,
        "Creates an FCB data structure and writes an U-Boot image to flash",
        "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
        "\t-f <part>\twrite bootloader image to partition <part>\n"
-       "\t-f #\twrite bootloader image at block # (decimal)\n"
-       "\t-r\twrite redundant bootloader image at next free block after first image\n"
+       "\t-f #\t\twrite bootloader image at block # (decimal)\n"
+       "\t-r\t\twrite redundant bootloader image at next free block after first image\n"
        "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
-       "\t-r #\twrite redundant bootloader image at block # (decimal)\n"
-       "\t-e #\tspecify number of redundant blocks per boot loader image\n"
-       "\t\tonly valid if -f or -r specify a flash address rather than a partition name\n"
-       "\t<address>\tRAM address of bootloader image (default: ${fileaddr}\n"
-       "\t<length>\tlength of bootloader image in RAM (default: ${filesize}"
+       "\t-r #\t\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\t\tspecify number of redundant blocks per boot loader image\n"
+       "\t\t\t(only valid if -f or -r specify a flash address rather than a partition name)\n"
+       "\t-n\t\tshow what would be done without actually updating the flash\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr})\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize})"
        );
index 16f78d3..561a1d1 100644 (file)
@@ -1,5 +1,7 @@
 #include <config.h>
+#include <asm-offsets.h>
 #include <configs/tx6.h>
+#include <linux/linkage.h>
 #include <asm/arch/imx-regs.h>
 #include <generated/asm-offsets.h>
 
@@ -87,6 +89,8 @@ dcd_start:
        .error  "DCD too large!"
        .endif
 dcd_end:
+       .section ".pad"
+       .section ".text"
        .endm
 
 #define MXC_DCD_CMD_WRT(type, flags)                                   \
@@ -107,6 +111,7 @@ dcd_end:
 #define CK_TO_NS(ck)   (((ck) * 1000 + SDRAM_CLK / 2) / SDRAM_CLK)
 #define NS_TO_CK(ns)   (((ns) * SDRAM_CLK + 999) / 1000)
 #define NS_TO_CK10(ns) DIV_ROUND_UP(NS_TO_CK(ns), 10)
+#define PS_TO_CK(ps)   DIV_ROUND_UP(NS_TO_CK(ps), 1000)
 
        .macro          CK_VAL, name, clks, offs, max
        .iflt           \clks - \offs
@@ -157,7 +162,7 @@ dcd_end:
 #define ADDR_MIRROR                    0
 #define DDR_TYPE                       MDMISC_DDR_TYPE_DDR3
 
-/* 512/1024MiB SDRAM: NT5CB128M16FP-DII */
+/* 512/1024MiB SDRAM: NT5CB128M16FP-DII or MT41K128M16JT-125 */
 #if SDRAM_CLK > 666 && SDRAM_CLK <= 800
 #define CL_VAL 11
 #define CWL_VAL        8
@@ -180,26 +185,26 @@ dcd_end:
 /* MDCFG0 0x0c */
 NS_VAL tRFC,   160, 1, 255             /* clks - 1 (0..255) */
 CK_MAX tXS,    NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
-CK_MAX tXP,    NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
-CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15  /* clks - 1 (0..15) */
-NS_VAL tFAW,   50, 1, 31               /* clks - 1 (0..31) */
+CK_MAX tXP,    NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) (MT41K128M16JT: 6ns) */
+CK_MAX tXPDLL, NS_TO_CK(24), 10, 1, 15 /* clks - 1 (0..15) */
+NS_VAL tFAW,   50, 1, 31               /* clks - 1 (0..31) (MT41K128M16JT: 30ns) */
 CK_VAL tCL,    CL_VAL, 3, 8            /* clks - 3 (0..8) CAS Latency */
 
 /* MDCFG1 0x10 */
-CK_VAL tRCD,   NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
-CK_VAL tRP,    NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
-NS_VAL tRC,    50, 1, 31               /* clks - 1 (0..31) */
-CK_VAL tRAS,   NS_TO_CK10(375), 1, 31  /* clks - 1 (0..31) */ /* 37.5 */
+CK_VAL tRCD,   PS_TO_CK(13750), 1, 7   /* clks - 1 (0..7) */ /* 13.75 (NT5CB128M16FP: 12.5ns) */
+CK_VAL tRP,    PS_TO_CK(13750), 1, 7   /* clks - 1 (0..7) */ /* 13.75 (NT5CB128M16FP: 12.5ns) */
+NS_VAL tRC,    50, 1, 31               /* clks - 1 (0..31) (MT41K128M16JT: 49ns) */
+CK_VAL tRAS,   NS_TO_CK10(375), 1, 31  /* clks - 1 (0..31) (MT41K128M16JT: 3.5ns) */
 CK_VAL tRPA,   1, 0, 1                 /* clks     (0..1) */
 NS_VAL tWR,    15, 1, 15               /* clks - 1 (0..15) */
 CK_VAL tMRD,   4, 1, 15                /* clks - 1 (0..15) */
 CK_VAL tCWL,   CWL_VAL, 2, 6           /* clks - 2 (0..6) */
 
 /* MDCFG2 0x14 */
-CK_VAL tDLLK,  512, 1, 511             /* clks - 1 (0..511) */
+CK_VAL tDLLK,  512, 1, 511             /* clks - 1 (0..511) */ /* (Jedec Standard) */
 CK_MAX tRTP,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
 CK_MAX tWTR,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
-CK_MAX tRRD,   NS_TO_CK(10), 4, 1, 7   /* clks - 1 (0..7) */
+CK_MAX tRRD,   NS_TO_CK(10), 4, 1, 7   /* clks - 1 (0..7) (MT41K128M16JT: 6ns) */
 
 /* MDOR 0x30 */
 CK_MAX tXPR,   NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
@@ -207,8 +212,8 @@ CK_MAX      tXPR,   NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) m
 #define tRST_CKE       (DIV_ROUND_UP(500000, MDOR_CLK_PERIOD_ns) + 2)
 
 /* MDOTC 0x08 */
-CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
-CK_VAL tAONPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
+CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 2ns .. 8.5ns */
+CK_VAL tAONPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 2ns .. 8.5ns */
 CK_VAL tANPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
 CK_VAL tAXPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
 CK_VAL tODTLon tCWL, 0, 7              /* clks - 1 (0..7) */ /* CWL+AL-2 */
@@ -313,11 +318,14 @@ CK_MAX    tCKSRE, NS_TO_CK(10), 5, 0, 7
                                ((PHYS_SDRAM_1_WIDTH / 32) << 16) |     \
                                ((-1) << (32 - BANK_ADDR_BITS)))
 
+#define MDMISC_WALAT(n)                (((n) & 3) << 16)
+#define MDMISC_RALAT(n)                (((n) & 7) << 6)
+
 #define MDMISC_VAL             ((ADDR_MIRROR << 19) |  \
-                               (WALAT << 16) |         \
+                               MDMISC_WALAT(WALAT) |   \
                                (BI_ON << 12) |         \
                                (0x3 << 9) |            \
-                               (RALAT << 6) |          \
+                               MDMISC_RALAT(RALAT) |   \
                                (DDR_TYPE << 3))
 
 #define MDOR_VAL               ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
@@ -329,6 +337,7 @@ CK_MAX      tCKSRE, NS_TO_CK(10), 5, 0, 7
                                (tODTLon << 12) |       \
                                (tODTLoff << 4))
 
+       .section ".ivt"
 ivt_header:
        .word   CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
 app_start_addr:
@@ -341,12 +350,16 @@ boot_data_ptr:
 self_ptr:
        .word   ivt_header
 app_code_csf:
+#ifdef CONFIG_SECURE_BOOT
+       .word   __csf_data
+#else
        .word   0x0
+#endif
        .word   0x0
 boot_data:
-       .long   _start
+       .long   CONFIG_SYS_TEXT_BASE
 image_len:
-       .long   CONFIG_U_BOOT_IMG_SIZE
+       .long   __uboot_img_len
 plugin:
        .word   0
 ivt_end:
@@ -399,7 +412,9 @@ ivt_end:
 #define MMDC1_MDRWD                            0x021b002c
 #define MMDC1_MDOR                             0x021b0030
 #define MMDC1_MDASP                            0x021b0040
+
 #define MMDC1_MAPSR                            0x021b0404
+
 #define MMDC1_MPZQHWCTRL                       0x021b0800
 #define MMDC1_MPWLGCR                          0x021b0808
 #define MMDC1_MPWLDECTRL0                      0x021b080c
@@ -432,6 +447,7 @@ ivt_end:
 
 #if PHYS_SDRAM_1_WIDTH == 64
 #define MMDC2_MDPDC                            0x021b4004
+
 #define MMDC2_MPWLGCR                          0x021b4808
 #define MMDC2_MPWLDECTRL0                      0x021b480c
 #define MMDC2_MPWLDECTRL1                      0x021b4810
@@ -468,15 +484,21 @@ ivt_end:
 #define MMDC2_MPSWDRDR5                                0x021b48ac
 #define MMDC2_MPSWDRDR6                                0x021b48b0
 #define MMDC2_MPSWDRDR7                                0x021b48b4
+#define MMDC2_MPMUR0                           0x021b48b8
 #endif
 
 #ifdef CONFIG_SOC_MX6Q
 #define IOMUXC_GPR1                            0x020e0004
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA20       0x020e00a0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e00a4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e00c4
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO16           0x020e0248
 #define IOMUXC_SW_MUX_CTL_PAD_GPIO17           0x020e024c
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7                0x020e02a8
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6                0x020e02ac
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0                0x020e02c0
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1                0x020e02c4
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2                0x020e02c8
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_CLE         0x020e02d4
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_ALE         0x020e02d8
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B                0x020e02dc
@@ -493,6 +515,10 @@ ivt_end:
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05      0x020e0310
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06      0x020e0314
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07      0x020e0318
+
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA20       0x020e03b4
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e03b8
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e03d8
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P     0x020e050c
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5                0x020e0510
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4                0x020e0514
@@ -537,6 +563,9 @@ ivt_end:
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6                0x020e05bc
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P     0x020e05c0
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7                0x020e05c4
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO16           0x020e0618
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO17           0x020e061c
+#define IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2                0x020e06b0
 #define IOMUXC_SW_PAD_CTL_GRP_B7DS             0x020e0748
 #define IOMUXC_SW_PAD_CTL_GRP_ADDDS            0x020e074c
 #define IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL      0x020e0750
@@ -561,17 +590,27 @@ ivt_end:
 #define IOMUXC_SW_PAD_CTL_GRP_B4DS             0x020e07a0
 #define IOMUXC_SW_PAD_CTL_GRP_B5DS             0x020e07a4
 #define IOMUXC_SW_PAD_CTL_GRP_B6DS             0x020e07a8
+
 #define IOMUXC_UART1_UART_RTS_B_SELECT_INPUT   0x020e091c
 #define IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT 0x020e0920
+
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0898
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e089c
+#define TX6_I2C1_SEL_INP_VAL                   1
 #endif
 
 #if defined(CONFIG_SOC_MX6DL) || defined(CONFIG_SOC_MX6S)
 #define IOMUXC_GPR1                            0x020e0004
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA20       0x020e0154
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e0158
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e0174
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO16           0x020e0214
 #define IOMUXC_SW_MUX_CTL_PAD_GPIO17           0x020e0218
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7                0x020e0330
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6                0x020e032c
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0                0x020e0314
 #define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1                0x020e0318
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2                0x020e031c
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_CLE         0x020e0270
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_ALE         0x020e026c
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B                0x020e02a8
@@ -588,6 +627,10 @@ ivt_end:
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05      0x020e0298
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06      0x020e029c
 #define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07      0x020e02a0
+
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA20       0x020e0524
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e0528
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e0544
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P     0x020e04d0
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5                0x020e0484
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4                0x020e0480
@@ -632,6 +675,9 @@ ivt_end:
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6                0x020e0488
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P     0x020e04d8
 #define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7                0x020e048c
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO16           0x020e05e4
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO17           0x020e05e8
+#define IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2                0x020e0704
 #define IOMUXC_SW_PAD_CTL_GRP_B7DS             0x020e0748
 #define IOMUXC_SW_PAD_CTL_GRP_ADDDS            0x020e074c
 #define IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL      0x020e0750
@@ -648,15 +694,37 @@ ivt_end:
 #define IOMUXC_SW_PAD_CTL_GRP_B4DS             0x020e07a0
 #define IOMUXC_SW_PAD_CTL_GRP_B5DS             0x020e07a4
 #define IOMUXC_SW_PAD_CTL_GRP_B6DS             0x020e07a8
+
 #define IOMUXC_UART1_UART_RTS_B_SELECT_INPUT   0x020e08f8
 #define IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT 0x020e08fc
+
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0868
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e086c
+#define TX6_I2C1_SEL_INP_VAL                   1
 #endif
 
 dcd_hdr:
        MXC_DCD_START
        MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       /* setup I2C pads for PMIC */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21, 0x00000016)
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28, 0x00000011)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21, 0x0000f079)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28, 0x0000f079)
+       MXC_DCD_ITEM(IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21, TX6_I2C1_SEL_INP_VAL)
+       MXC_DCD_ITEM(IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28, TX6_I2C1_SEL_INP_VAL)
+
+       /* ENET_REF_CLK */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_GPIO16, 0x00000012)
+       /* ETN PHY nRST */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2, 0x00000015)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2, 0x000030b0)
+       /* ETN PHY Power */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_EIM_DATA20, 0x00000015)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_EIM_DATA20, 0x000030b0)
        /* RESET_OUT GPIO_7_12 */
        MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_GPIO17, 0x00000005)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_GPIO17, 0x000030b0)
 
        MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CS2CDR, 0x006336c1) /* default: 0x007236c1 */
        MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CHSCCDR, 0x00012093) /* default: 0x0002a150 */
@@ -815,7 +883,11 @@ dcd_hdr:
 
        /* MDCTL */
        MXC_DCD_ITEM(MMDC1_MDCTL, MDCTL_VAL)
-       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, MMDC1_MDMISC, 0x40000000)
+#if BANK_ADDR_BITS > 1
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, MMDC1_MDMISC, (3 << 30))
+#else
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, MMDC1_MDMISC, (1 << 30))
+#endif
        MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
 
        MXC_DCD_ITEM(MMDC1_MDCFG0, MDCFG0_VAL)
@@ -825,7 +897,6 @@ dcd_hdr:
        MXC_DCD_ITEM(MMDC1_MDOR,   MDOR_VAL)
        MXC_DCD_ITEM(MMDC1_MDOTC,  MDOTC_VAL)
        MXC_DCD_ITEM(MMDC1_MDPDC,  MDPDC_VAL_0)
-       MXC_DCD_ITEM_64(MMDC2_MDPDC,  MDPDC_VAL_0)
        MXC_DCD_ITEM(MMDC1_MDASP,  (PHYS_SDRAM_1_SIZE + SZ_256M) / SZ_32M - 1)
 
        /* CS0 MRS: */
@@ -849,7 +920,7 @@ dcd_hdr:
 
        /* DDR3 calibration */
        MXC_DCD_ITEM(MMDC1_MPPDCMPR2, 0x00000003) /* select default compare pattern for DQ calibration */
-       MXC_DCD_ITEM(MMDC1_MAPSR,     0x00001007)
+       MXC_DCD_ITEM(MMDC1_MAPSR, 1)
 
        /* ZQ calibration */
        MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008010) /* precharge all */
@@ -871,6 +942,10 @@ dcd_hdr:
 #define WL_DLY_DQS6    (WL_DLY_DQS_VAL + 0)
 #define WL_DLY_DQS7    (WL_DLY_DQS_VAL + 0)
        /* Write leveling */
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_SET)
+       MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_RALAT(~0) | MDMISC_WALAT(~0)) /* increase WALAT/RALAT to max. */
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
        MXC_DCD_ITEM(MMDC1_MPWLDECTRL0, (WL_DLY_DQS1 << 16) | (WL_DLY_DQS0 << 0))
        MXC_DCD_ITEM_32(MMDC1_MPWLDECTRL1, (WL_DLY_DQS3 << 16) | (WL_DLY_DQS2 << 0))
        MXC_DCD_ITEM_64(MMDC2_MPWLDECTRL0, (WL_DLY_DQS5 << 16) | (WL_DLY_DQS4 << 0))
@@ -893,30 +968,28 @@ dcd_hdr:
        MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK | 0x7000)
        MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK | 0x7000)
 
-       MXC_DCD_ITEM(MMDC1_MDSCR, 0x00008020) /* issue one refresh cycle */
        MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
 
        MXC_DCD_ITEM(MMDC1_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
        MXC_DCD_ITEM(MMDC1_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
        MXC_DCD_ITEM_64(MMDC2_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
        MXC_DCD_ITEM_64(MMDC2_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
+#define MPMUR_FRC_MSR  (1 << 11)
+       MXC_DCD_ITEM(MMDC1_MPMUR0, MPMUR_FRC_MSR)
+       MXC_DCD_ITEM_64(MMDC2_MPMUR0, MPMUR_FRC_MSR)
 #ifdef DO_DDR_CALIB
-       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x80000000) /* issue fifo reset */
-       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x80000000)
-       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
-       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x80000000) /* issue 2nd fifo reset */
-       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x80000000)
-       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
-       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x50800000) /* choose 32 wait cycles and start DQS calib. */
-       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x10001000)
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, (1 << 30) | (1 << 28) | (0 << 23)) /* choose 32 wait cycles and start DQS calib. */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_ANY_CLR, MMDC1_MPDGCTRL0, 0x10001000)
        MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
 #else /* DO_DDR_CALIB */
-#define MPMUR_FRC_MSR  (1 << 11)
        MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x41e20160)
        MXC_DCD_ITEM(MMDC1_MPDGCTRL1, 0x014d014f)
        MXC_DCD_ITEM_64(MMDC2_MPDGCTRL0, 0x014f0150)
        MXC_DCD_ITEM_64(MMDC2_MPDGCTRL1, 0x0144014a)
+       MXC_DCD_ITEM(MMDC1_MPMUR0, MPMUR_FRC_MSR)
+       MXC_DCD_ITEM_64(MMDC2_MPMUR0, MPMUR_FRC_MSR)
 #endif /* DO_DDR_CALIB */
+       MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL)
        /* DRAM_SDQS[0..7] pad config */
        MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P, SDQS_MASK)
        MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P, SDQS_MASK)
@@ -957,6 +1030,7 @@ dcd_hdr:
        MXC_DCD_ITEM(MMDC1_MPWRDLCTL, 0x3f3f3f3f)
        MXC_DCD_ITEM_64(MMDC2_MPWRDLCTL, 0x3f3f3f3f)
        MXC_DCD_ITEM(MMDC1_MPMUR0, MPMUR_FRC_MSR)
+       MXC_DCD_ITEM_64(MMDC2_MPMUR0, MPMUR_FRC_MSR)
 #endif /* DO_DDR_CALIB */
        MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
 #if BANK_ADDR_BITS > 1
@@ -964,9 +1038,8 @@ dcd_hdr:
 #endif
        MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa138002b)
        MXC_DCD_ITEM(MMDC1_MDREF, (3 << 11) | (0 << 14)) /* 4 cycles per 64kHz period (3.9us) */
-       MXC_DCD_ITEM(MMDC1_MAPSR, 0x00001006)
+       MXC_DCD_ITEM(MMDC1_MAPSR, (16 << 8))
        MXC_DCD_ITEM(MMDC1_MDPDC, MDPDC_VAL_1)
-       MXC_DCD_ITEM_64(MMDC2_MDPDC, MDPDC_VAL_1)
 
        /* MDSCR: Normal operation */
        MXC_DCD_ITEM(MMDC1_MDSCR, 0x00000000)
index 53cf5e2..3f692d3 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 
+#include "../common/karo.h"
 #include "pmic.h"
 
 #define LTC3676_BUCK1          0x01
index 2743dad..a29a74b 100644 (file)
@@ -14,7 +14,6 @@
  * GNU General Public License for more details.
  *
  */
-
 #include <common.h>
 #include <errno.h>
 #include <i2c.h>
@@ -36,15 +35,23 @@ static struct {
 #endif
 };
 
-int tx6_pmic_init(void)
+int tx6_pmic_init(int addr)
 {
        int ret = -ENODEV;
        int i;
 
+       debug("Probing for I2C dev 0x%02x\n", addr);
        for (i = 0; i < ARRAY_SIZE(i2c_addrs); i++) {
-               ret = i2c_probe(i2c_addrs[i].addr);
+               u8 i2c_addr = i2c_addrs[i].addr;
+
+               if (i2c_addr != addr)
+                       continue;
+
+               debug("Probing for I2C dev 0x%02x\n", i2c_addr);
+               ret = i2c_probe(i2c_addr);
                if (ret == 0) {
-                       i2c_addrs[i].init(i2c_addrs[i].addr);
+                       debug("Initializing PMIC at I2C addr 0x%02x\n", i2c_addr);
+                       ret = i2c_addrs[i].init(i2c_addr);
                        break;
                }
        }
index 4786eef..1b301b7 100644 (file)
@@ -19,4 +19,4 @@ int ltc3676_pmic_setup(uchar addr);
 int rn5t618_pmic_setup(uchar addr);
 int rn5t567_pmic_setup(uchar addr);
 
-int tx6_pmic_init(void);
+int tx6_pmic_init(int addr);
index 6f79137..913dd2c 100644 (file)
@@ -18,6 +18,7 @@
 #include <common.h>
 #include <i2c.h>
 
+#include "../common/karo.h"
 #include "pmic.h"
 
 #define RN5T567_NOETIMSET      0x11
index 19aba87..8737e76 100644 (file)
@@ -18,6 +18,7 @@
 #include <common.h>
 #include <i2c.h>
 
+#include "../common/karo.h"
 #include "pmic.h"
 
 #define RN5T618_NOETIMSET      0x11
index 15340db..1d09de4 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/gpio.h>
 #include <asm/arch/mx6-pins.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/hab.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/sys_proto.h>
@@ -50,6 +51,8 @@
 #define TX6_LCD_BACKLIGHT_GPIO         IMX_GPIO_NR(1, 1)
 
 #define TX6_RESET_OUT_GPIO             IMX_GPIO_NR(7, 12)
+#define TX6_I2C1_SCL_GPIO              IMX_GPIO_NR(3, 21)
+#define TX6_I2C1_SDA_GPIO              IMX_GPIO_NR(3, 28)
 
 #ifdef CONFIG_MX6_TEMPERATURE_MIN
 #define TEMPERATURE_MIN                        CONFIG_MX6_TEMPERATURE_MIN
@@ -70,26 +73,12 @@ enum {
        MX6_PAD_DECL(GARBAGE, 0, 0, 0, 0, 0, 0)
 };
 
-static const iomux_v3_cfg_t const tx6qdl_pads[] = {
-       MX6_PAD_GARBAGE,
-#ifdef CONFIG_TX6_NAND_
-       /* NAND flash pads */
-       MX6_PAD_NANDF_CLE__NAND_CLE,
-       MX6_PAD_NANDF_ALE__NAND_ALE,
-       MX6_PAD_NANDF_WP_B__NAND_RESETN,
-       MX6_PAD_NANDF_RB0__NAND_READY0,
-       MX6_PAD_NANDF_CS0__NAND_CE0N,
-       MX6_PAD_SD4_CMD__NAND_RDN,
-       MX6_PAD_SD4_CLK__NAND_WRN,
-       MX6_PAD_NANDF_D0__NAND_D0,
-       MX6_PAD_NANDF_D1__NAND_D1,
-       MX6_PAD_NANDF_D2__NAND_D2,
-       MX6_PAD_NANDF_D3__NAND_D3,
-       MX6_PAD_NANDF_D4__NAND_D4,
-       MX6_PAD_NANDF_D5__NAND_D5,
-       MX6_PAD_NANDF_D6__NAND_D6,
-       MX6_PAD_NANDF_D7__NAND_D7,
+char __uboot_img_end[0] __attribute__((section(".__uboot_img_end")));
+#ifdef CONFIG_SECURE_BOOT
+char __csf_data[0] __attribute__((section(".__csf_data")));
 #endif
+
+static const iomux_v3_cfg_t const tx6qdl_pads[] = {
        /* RESET_OUT */
        MX6_PAD_GPIO_17__GPIO7_IO12,
 
@@ -136,7 +125,17 @@ static const iomux_v3_cfg_t const tx6qdl_fec_pads[] = {
        MX6_PAD_ENET_TXD0__ENET_TX_DATA0,
 };
 
+static const iomux_v3_cfg_t const tx6_i2c_pads[] = {
+       /* internal I2C */
+       MX6_PAD_EIM_D28__I2C1_SDA,
+       MX6_PAD_EIM_D21__I2C1_SCL,
+};
+
 static const struct gpio const tx6qdl_gpios[] = {
+       /* These two entries are used to forcefully reinitialize the I2C bus */
+       { TX6_I2C1_SCL_GPIO, GPIOFLAG_INPUT, "I2C1 SCL", },
+       { TX6_I2C1_SDA_GPIO, GPIOFLAG_INPUT, "I2C1 SDA", },
+
        { TX6_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "#RESET_OUT", },
        { TX6_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
        { TX6_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RESET", },
@@ -247,9 +246,6 @@ static void tx6qdl_print_cpuinfo(void)
 
 int board_early_init_f(void)
 {
-       gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios));
-       imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads));
-
        return 0;
 }
 
@@ -258,11 +254,162 @@ static bool tx6_temp_check_enabled = true;
 #else
 #define tx6_temp_check_enabled 0
 #endif
+static int pmic_addr __data;
+
+#if defined(CONFIG_SOC_MX6Q)
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e00a4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e00c4
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e03b8
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e03d8
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0898
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e089c
+#define I2C1_SEL_INPUT_VAL                     0
+#endif
+#if defined(CONFIG_SOC_MX6DL) || defined(CONFIG_SOC_MX6S)
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e0158
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e0174
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e0528
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e0544
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0868
+#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e086c
+#define I2C1_SEL_INPUT_VAL                     1
+#endif
+
+#define GPIO_DR 0
+#define GPIO_DIR 4
+#define GPIO_PSR 8
+
+static const struct i2c_gpio_regs {
+       const char *label;
+       u32 gpio;
+       unsigned long gpio_base;
+       unsigned long muxctl;
+       unsigned long padctl;
+       unsigned long sel_input;
+} tx6_i2c_iomux_regs[] = {
+       {
+               .label = "PMIC SCL",
+               .gpio = TX6_I2C1_SCL_GPIO,
+               .gpio_base = GPIO3_BASE_ADDR,
+               .muxctl = IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21,
+               .padctl = IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21,
+               .sel_input = IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21,
+       }, {
+               .label = "PMIC SDA",
+               .gpio = TX6_I2C1_SDA_GPIO,
+               .gpio_base = GPIO3_BASE_ADDR,
+               .muxctl = IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28,
+               .padctl = IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28,
+               .sel_input = IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28,
+       },
+};
+
+static inline u32 __tx6_readl(void *addr,
+                       const char *fn, int ln)
+{
+       u32 val = readl(addr);
+       debug("%s@%d: read %08x from %p\n", fn, ln, val, addr);
+       return val;
+}
+#undef readl
+#define readl(a)       __tx6_readl((void *)(a), __func__, __LINE__)
+
+static inline void __tx6_writel(u32 val, void *addr,
+                               const char *fn, int ln)
+{
+       debug("%s@%d: writing %08x to %p\n", fn, ln, val, addr);
+       writel(val, addr);
+}
+#undef writel
+#define writel(v, a)   __tx6_writel(v, (void *)(a), __func__, __LINE__)
+
+static void tx6_i2c_recover(void)
+{
+       int i;
+       int bad = 0;
+       int failed = 0;
+#define MAX_TRIES 100
+
+       debug("Clearing I2C bus\n");
+
+       for (i = 0; i < ARRAY_SIZE(tx6_i2c_iomux_regs); i++) {
+               int gpio = tx6_i2c_iomux_regs[i].gpio;
+               u32 gpio_mask = 1 << (gpio % 32);
+
+               void *gpio_base = (void *)tx6_i2c_iomux_regs[i].gpio_base;
+
+               if ((readl(gpio_base + GPIO_PSR) & gpio_mask) == 0) {
+                       int retries = MAX_TRIES;
+
+                       bad++;
+                       printf("%s (GPIO%u_%u) is not HIGH\n",
+                               tx6_i2c_iomux_regs[i].label,
+                               gpio / 32 + 1, gpio % 32);
+                       writel(readl(gpio_base + GPIO_DR) | gpio_mask,
+                               gpio_base + GPIO_DR);
+                       writel(readl(gpio_base + GPIO_DIR) | gpio_mask,
+                               gpio_base + GPIO_DIR);
+                       writel(0x15, tx6_i2c_iomux_regs[i].muxctl);
+                       writel(0x0f079, tx6_i2c_iomux_regs[i].padctl);
+                       writel(I2C1_SEL_INPUT_VAL, tx6_i2c_iomux_regs[i].sel_input);
+                       if ((readl(gpio_base + GPIO_DR) & gpio_mask) == 0)
+                               hang();
+                       if ((readl(gpio_base + GPIO_DIR) & gpio_mask) == 0)
+                               hang();
+                       while ((readl(gpio_base + GPIO_PSR) & gpio_mask) == 0 &&
+                               retries-- > 0) {
+                               udelay(100);
+                       }
+                       writel(readl(gpio_base + GPIO_DIR) & ~gpio_mask,
+                               gpio_base + GPIO_DIR);
+
+                       if ((readl(gpio_base + GPIO_PSR) & gpio_mask) == 0) {
+                               printf("Failed to force %s (GPIO%u_%u) HIGH\n",
+                                       tx6_i2c_iomux_regs[i].label,
+                                       gpio / 32 + 1, gpio % 32);
+                               failed++;
+                       } else if (retries < MAX_TRIES) {
+                               printf("%s (GPIO%u_%u) forced HIGH after %u loops\n",
+                                       tx6_i2c_iomux_regs[i].label,
+                                       gpio / 32 + 1, gpio % 32,
+                                       MAX_TRIES - retries);
+                       }
+               } else {
+                       debug("%s (GPIO%u_%u) is HIGH\n",
+                               tx6_i2c_iomux_regs[i].label,
+                               gpio / 32 + 1, gpio % 32);
+               }
+       }
+       debug("Setting up I2C Pads\n");
+       imx_iomux_v3_setup_multiple_pads(tx6_i2c_pads,
+                                       ARRAY_SIZE(tx6_i2c_pads));
+       if (bad) {
+               if (failed)
+                       printf("I2C bus recovery FAILED\n");
+               else
+                       printf("I2C bus recovery succeeded\n");
+       }
+}
+
+#define pr_reg(b, n)   debug("%12s@%p=%08x\n", #n, (void *)(b) + (n), readl((b) + (n)))
+
+static inline void dump_regs(void)
+{
+       pr_reg(GPIO3_BASE_ADDR, GPIO_DR);
+       pr_reg(GPIO3_BASE_ADDR, GPIO_DIR);
+       pr_reg(GPIO3_BASE_ADDR, GPIO_PSR);
+}
 
 int board_init(void)
 {
        int ret;
 
+       ret = gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios));
+       if (ret < 0) {
+               printf("Failed to request tx6qdl_gpios: %d\n", ret);
+       }
+       imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads));
+
        /* Address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
        gd->bd->bi_arch_number = -1;
@@ -275,12 +422,12 @@ int board_init(void)
 #ifndef CONFIG_MX6_TEMPERATURE_HOT
                tx6_temp_check_enabled = false;
 #endif
-               return 1;
+               return 0;
        }
 
-       ret = tx6_pmic_init();
+       ret = tx6_pmic_init(pmic_addr);
        if (ret) {
-               printf("Failed to setup PMIC voltages\n");
+               printf("Failed to setup PMIC voltages: %d\n", ret);
                hang();
        }
        return 0;
@@ -290,7 +437,7 @@ int dram_init(void)
 {
        /* dram_init must store complete ramsize in gd->ram_size */
        gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
-                               PHYS_SDRAM_1_SIZE);
+                               PHYS_SDRAM_1_SIZE * CONFIG_NR_DRAM_BANKS);
        return 0;
 }
 
@@ -306,8 +453,8 @@ void dram_init_banksize(void)
 #endif
 }
 
-#ifdef CONFIG_CMD_MMC
-#define SD_PAD_CTRL (PAD_CTL_PUS_47K_UP |                      \
+#ifdef CONFIG_FSL_ESDHC
+#define SD_PAD_CTRL (PAD_CTL_PUS_47K_UP |              \
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |         \
        PAD_CTL_SRE_FAST)
 
@@ -342,7 +489,8 @@ static const iomux_v3_cfg_t mmc3_pads[] = {
        MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
        MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
        /* eMMC RESET */
-       MX6_PAD_NANDF_ALE__SD4_RESET,
+       MX6_PAD_NANDF_ALE__SD4_RESET | MUX_PAD_CTRL(PAD_CTL_PUS_47K_UP |
+                                               PAD_CTL_DSE_40ohm),
 };
 #endif
 
@@ -645,7 +793,6 @@ static struct fb_videomode tx6_fb_modes[] = {
                .upper_margin   = 2,
                .vsync_len      = 10,
                .lower_margin   = 2,
-               .sync           = FB_SYNC_CLK_LAT_FALL,
        },
        {
                /* Emerging ET0500G0DH6 800 x 480 display.
@@ -764,9 +911,9 @@ void lcd_enable(void)
         */
        lcd_is_enabled = 0;
 
-       karo_load_splashimage(1);
-
        if (lcd_enabled) {
+               karo_load_splashimage(1);
+
                debug("Switching LCD on\n");
                gpio_set_value(TX6_LCD_PWR_GPIO, 1);
                udelay(100);
@@ -1090,7 +1237,13 @@ void lcd_ctrl_init(void *lcdbase)
 
 static void stk5_board_init(void)
 {
-       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       int ret;
+
+       ret = gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       if (ret < 0) {
+               printf("Failed to request stk5_gpios: %d\n", ret);
+               return;
+       }
        imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
 }
 
@@ -1101,10 +1254,17 @@ static void stk5v3_board_init(void)
 
 static void stk5v5_board_init(void)
 {
+       int ret;
+
        stk5_board_init();
 
-       gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
+       ret = gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
                        "Flexcan Transceiver");
+       if (ret) {
+               printf("Failed to request Flexcan Transceiver GPIO: %d\n", ret);
+               return;
+       }
+
        imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO4_IO21);
 }
 
@@ -1133,6 +1293,13 @@ int board_late_init(void)
 {
        int ret = 0;
        const char *baseboard;
+#if 1
+       /* override secure_boot fuse */
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank0_regs *fuse = (void *)ocotp->bank[0].fuse_regs;
+
+       writel(0x12, &fuse->cfg5);
+#endif
 
        env_cleanup();
 
@@ -1234,37 +1401,54 @@ static struct {
        { 0x33, 3, },
 };
 
-static int tx6_get_mod_rev(void)
+static int tx6_get_mod_rev(unsigned int pmic_id)
+{
+       if (pmic_id < ARRAY_SIZE(tx6_mod_revs))
+               return tx6_mod_revs[pmic_id].rev;
+
+       return 0;
+}
+
+static int tx6_pmic_probe(void)
 {
        int i;
 
+       tx6_i2c_recover();
+       i2c_init_all();
+
        for (i = 0; i < ARRAY_SIZE(tx6_mod_revs); i++) {
-               int ret = i2c_probe(tx6_mod_revs[i].addr);
+               u8 i2c_addr = tx6_mod_revs[i].addr;
+               int ret = i2c_probe(i2c_addr);
+
                if (ret == 0) {
-                       debug("I2C probe succeeded for addr %02x\n", tx6_mod_revs[i].addr);
-                       return tx6_mod_revs[i].rev;
+                       debug("I2C probe succeeded for addr 0x%02x\n", i2c_addr);
+                       return i;
                }
-               debug("I2C probe returned %d for addr %02x\n", ret,
-                       tx6_mod_revs[i].addr);
+               debug("I2C probe returned %d for addr 0x%02x\n", ret, i2c_addr);
        }
-       return 0;
+       return -EINVAL;
 }
 
 int checkboard(void)
 {
        u32 cpurev = get_cpu_rev();
        int cpu_variant = (cpurev >> 12) & 0xff;
+       int pmic_id;
 
        tx6qdl_print_cpuinfo();
 
-       i2c_init(CONFIG_SYS_I2C_SPEED, 0 /* unused */);
+       pmic_id = tx6_pmic_probe();
+       if (pmic_id >= 0)
+               pmic_addr = tx6_mod_revs[pmic_id].addr;
 
        printf("Board: Ka-Ro TX6%s-%d%d%d%c\n",
                tx6_mod_suffix,
                cpu_variant == MXC_CPU_MX6Q ? 1 : 8,
-               is_lvds(), tx6_get_mod_rev(),
+               is_lvds(), tx6_get_mod_rev(pmic_id),
                tx6_mem_suffix());
 
+       get_hab_status();
+
        return 0;
 }
 
index 4578feb..c4e0e21 100644 (file)
@@ -27,13 +27,17 @@ SECTIONS
        . = 0x00000000;
        .text :
        {
+               __uboot_img_start = .;
+               . = 0x400;
+               __ivt_start = .;
+               KEEP(*(.ivt*))
+               . = 0x1000;
+               __ivt_end = .;
                *(.__image_copy_start)
                *(.vectors)
                CPUDIR/start.o (.text*)
-               . = 0x400;
-               KEEP(board/karo/tx6/lowlevel_init.o (.text*))
                *(.text*)
-       }
+       } = 0xadde01f0
 
        . = ALIGN(4);
        .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
@@ -41,9 +45,9 @@ SECTIONS
        . = ALIGN(4);
        .data : {
                *(.data*)
+               . = ALIGN(4);
        }
 
-       . = ALIGN(4);
        .u_boot_list : {
                KEEP(*(SORT(.u_boot_list*)));
        }
@@ -69,12 +73,28 @@ SECTIONS
                *(.__rel_dyn_end)
        }
 
-       .end :
+       .pad :
        {
-               *(.__end)
+               *(.pad)
+               . = ALIGN(4096);
+       } = 0x01f0adde
+
+       _image_binary_end = . + (__ivt_end - __uboot_img_start);
+
+       .uboot_img_end :
+       {
+               KEEP(*(.__uboot_img_end))
        }
 
-       _image_binary_end = .;
+#ifdef CONFIG_SECURE_BOOT
+       . = CONFIG_SYS_TEXT_BASE + 0x70000;
+       .csf_data :
+       {
+               *(.__csf_data)
+               . = . + 0x2000;
+       }
+#endif
+       __uboot_img_len = . - __uboot_img_start;
 
 /*
  * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
@@ -94,26 +114,18 @@ SECTIONS
        .bss_end __bss_limit (OVERLAY) : {
                KEEP(*(.__bss_end));
        }
-       .dynsym _image_binary_end : { *(.dynsym) }
-       .dynbss : { *(.dynbss) }
-       .dynstr : { *(.dynstr*) }
-       .dynamic : { *(.dynamic*) }
-       .plt : { *(.plt*) }
-       .interp : { *(.interp*) }
-       .gnu.hash : { *(.gnu.hash) }
-       .gnu : { *(.gnu*) }
-       .ARM.exidx : { *(.ARM.exidx*) }
-       .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
 
-/*
-       /DISCARD/ : { *(.bss*) }
+       .dynsym _image_binary_end : { *(.dynsym) }
+       /DISCARD/ : { *(.debug*) }
+       /DISCARD/ : { *(.note*) }
+       /DISCARD/ : { *(.comment*) }
+       /DISCARD/ : { *(.dynbss) }
        /DISCARD/ : { *(.dynstr*) }
-       /DISCARD/ : { *(.dynsym*) }
        /DISCARD/ : { *(.dynamic*) }
-       /DISCARD/ : { *(.hash*) }
        /DISCARD/ : { *(.plt*) }
        /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu.hash) }
        /DISCARD/ : { *(.gnu*) }
-*/
+       /DISCARD/ : { *(.ARM.exidx*) }
+       /DISCARD/ : { *(.gnu.linkonce.armexidx.*) }
 }
index ead783c..da18c7a 100644 (file)
@@ -440,6 +440,11 @@ config CMD_TIME
        help
          Run commands and summarize execution time.
 
+config CMD_FUSE
+       bool "fuse read/write"
+       help
+         eFuse reading and programming support
+
 # TODO: rename to CMD_SLEEP
 config CMD_MISC
        bool "sleep"
index d4bc0f6..4d4f77a 100644 (file)
@@ -63,13 +63,13 @@ static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                printf("Reading bank %u:\n", bank);
                for (i = 0; i < cnt; i++, word++) {
                        if (!(i % 4))
-                               printf("\nWord 0x%.8x:", word);
+                               printf("\nWord 0x%08x:", word);
 
                        ret = fuse_read(bank, word, &val);
                        if (ret)
                                goto err;
 
-                       printf(" %.8x", val);
+                       printf(" %08x", val);
                }
                putc('\n');
        } else if (!strcmp(op, "sense")) {
@@ -81,13 +81,13 @@ static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                printf("Sensing bank %u:\n", bank);
                for (i = 0; i < cnt; i++, word++) {
                        if (!(i % 4))
-                               printf("\nWord 0x%.8x:", word);
+                               printf("\nWord 0x%08x:", word);
 
                        ret = fuse_sense(bank, word, &val);
                        if (ret)
                                goto err;
 
-                       printf(" %.8x", val);
+                       printf(" %08x", val);
                }
                putc('\n');
        } else if (!strcmp(op, "prog")) {
@@ -98,7 +98,7 @@ static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                        if (strtou32(argv[i], 16, &val))
                                return CMD_RET_USAGE;
 
-                       printf("Programming bank %u word 0x%.8x to 0x%.8x...\n",
+                       printf("Programming bank %u word 0x%08x to 0x%08x...\n",
                                        bank, word, val);
                        if (!confirmed && !confirm_prog())
                                return CMD_RET_FAILURE;
@@ -114,8 +114,8 @@ static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                        if (strtou32(argv[i], 16, &val))
                                return CMD_RET_USAGE;
 
-                       printf("Overriding bank %u word 0x%.8x with "
-                                       "0x%.8x...\n", bank, word, val);
+                       printf("Overriding bank %u word 0x%08x with 0x%08x...\n",
+                               bank, word, val);
                        ret = fuse_override(bank, word, val);
                        if (ret)
                                goto err;
index c89782a..f9378de 100644 (file)
@@ -11,7 +11,7 @@
 
 static int curr_device = -1;
 #ifndef CONFIG_GENERIC_MMC
-int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_mmc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        int dev;
 
@@ -137,6 +137,7 @@ static void print_mmcinfo(struct mmc *mmc)
                }
        }
 }
+
 static struct mmc *init_mmc_device(int dev, bool force_init)
 {
        struct mmc *mmc;
@@ -151,6 +152,7 @@ static struct mmc *init_mmc_device(int dev, bool force_init)
                return NULL;
        return mmc;
 }
+
 static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        struct mmc *mmc;
@@ -184,6 +186,7 @@ static int confirm_key_prog(void)
        puts("Authentication key programming aborted\n");
        return 0;
 }
+
 static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
                          int argc, char * const argv[])
 {
@@ -202,6 +205,7 @@ static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
        }
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
                           int argc, char * const argv[])
 {
@@ -230,6 +234,7 @@ static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
                return CMD_RET_FAILURE;
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
                            int argc, char * const argv[])
 {
@@ -256,6 +261,7 @@ static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
                return CMD_RET_FAILURE;
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag,
                              int argc, char * const argv[])
 {
@@ -353,6 +359,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
+
 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
                        int argc, char * const argv[])
 {
@@ -383,6 +390,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
+
 static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
                        int argc, char * const argv[])
 {
@@ -411,6 +419,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
+
 static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
                         int argc, char * const argv[])
 {
@@ -422,6 +431,7 @@ static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
 
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
                       int argc, char * const argv[])
 {
@@ -441,6 +451,7 @@ static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
        puts("get mmc type error!\n");
        return CMD_RET_FAILURE;
 }
+
 static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
                      int argc, char * const argv[])
 {
@@ -482,6 +493,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
 
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
                       int argc, char * const argv[])
 {
@@ -630,8 +642,7 @@ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
 
        if (!mmc_hwpart_config(mmc, &pconf, mode)) {
                if (mode == MMC_HWPART_CONF_COMPLETE)
-                       puts("Partitioning successful, "
-                            "power-cycle to make effective\n");
+                       puts("Partitioning successful, power-cycle to make effective\n");
                return CMD_RET_SUCCESS;
        } else {
                puts("Failed!\n");
@@ -646,50 +657,97 @@ static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
        int dev;
        struct mmc *mmc;
        u8 width, reset, mode;
+       int ret;
+       char *end;
 
        if (argc != 5)
                return CMD_RET_USAGE;
-       dev = simple_strtoul(argv[1], NULL, 10);
-       width = simple_strtoul(argv[2], NULL, 10);
-       reset = simple_strtoul(argv[3], NULL, 10);
-       mode = simple_strtoul(argv[4], NULL, 10);
+
+       dev = simple_strtoul(argv[1], &end, 10);
+       if (dev < 0 || dev >= get_mmc_dev_count() || *end != '\0') {
+               printf("Invalid mmc device '%s'; should be [0..%u]\n",
+                       argv[1], get_mmc_dev_count() - 1);
+               return CMD_RET_FAILURE;
+       }
+
+       width = simple_strtoul(argv[2], &end, 10);
+       if (width > 2 || *end != '\0') {
+               printf("Invalid boot_bus_width parameter '%s'; expected [0..2]\n",
+                       argv[2]);
+               return CMD_RET_FAILURE;
+       }
+
+       reset = simple_strtoul(argv[3], &end, 10);
+       if (reset > 1 || *end != '\0') {
+               printf("Invalid reset_boot_bus_width parameter '%s'; expected 0 or 1\n",
+                       argv[3]);
+               return CMD_RET_FAILURE;
+       }
+       mode = simple_strtoul(argv[4], &end, 10);
+       if (mode > 2 || *end != '\0') {
+               printf("Invalid boot_mode parameter '%s'; expected [0..2]\n",
+                       argv[4]);
+               return CMD_RET_FAILURE;
+       }
 
        mmc = init_mmc_device(dev, false);
-       if (!mmc)
+       if (!mmc) {
+               printf("Failed to init MMC device %d\n", dev);
                return CMD_RET_FAILURE;
+       }
 
        if (IS_SD(mmc)) {
                puts("BOOT_BUS_WIDTH only exists on eMMC\n");
                return CMD_RET_FAILURE;
        }
 
-       /* acknowledge to be sent during boot operation */
-       return mmc_set_boot_bus_width(mmc, width, reset, mode);
+       ret = mmc_set_boot_bus_width(mmc, width, reset, mode);
+       if (ret)
+               printf("Setting boot bus width failed: %d\n", ret);
+       return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
+
 static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag,
                              int argc, char * const argv[])
 {
        int dev;
        struct mmc *mmc;
        u32 bootsize, rpmbsize;
+       int ret;
+       char *end;
 
        if (argc != 4)
                return CMD_RET_USAGE;
-       dev = simple_strtoul(argv[1], NULL, 10);
-       bootsize = simple_strtoul(argv[2], NULL, 10);
-       rpmbsize = simple_strtoul(argv[3], NULL, 10);
+
+       dev = simple_strtoul(argv[1], &end, 10);
+       if (dev < 0 || dev >= get_mmc_dev_count() || *end != '\0') {
+               printf("Invalid mmc device '%s'; should be [0..%u]\n",
+                       argv[1], get_mmc_dev_count() - 1);
+               return CMD_RET_FAILURE;
+       }
+
+       bootsize = simple_strtoul(argv[2], &end, 10);
+       if (bootsize > 64 || *end != '\0') {
+               return CMD_RET_FAILURE;
+       }
+
+       rpmbsize = simple_strtoul(argv[3], &end, 10);
+       if (rpmbsize > 64 || *end != '\0') {
+               return CMD_RET_FAILURE;
+       }
 
        mmc = init_mmc_device(dev, false);
        if (!mmc)
                return CMD_RET_FAILURE;
 
        if (IS_SD(mmc)) {
-               printf("It is not a EMMC device\n");
+               printf("mmc device %d is not an EMMC device\n", dev);
                return CMD_RET_FAILURE;
        }
 
-       if (mmc_boot_partition_size_change(mmc, bootsize, rpmbsize)) {
-               printf("EMMC boot partition Size change Failed.\n");
+       ret = mmc_boot_partition_size_change(mmc, bootsize, rpmbsize);
+       if (ret) {
+               printf("EMMC boot partition size change failed: %d\n", ret);
                return CMD_RET_FAILURE;
        }
 
@@ -697,20 +755,43 @@ static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag,
        printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
        return CMD_RET_SUCCESS;
 }
+
 static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag,
                           int argc, char * const argv[])
 {
        int dev;
        struct mmc *mmc;
        u8 ack, part_num, access;
+       char *end;
+       int ret;
 
        if (argc != 5)
                return CMD_RET_USAGE;
 
-       dev = simple_strtoul(argv[1], NULL, 10);
-       ack = simple_strtoul(argv[2], NULL, 10);
-       part_num = simple_strtoul(argv[3], NULL, 10);
-       access = simple_strtoul(argv[4], NULL, 10);
+       dev = simple_strtoul(argv[1], &end, 10);
+       if (dev < 0 || dev >= get_mmc_dev_count() || *end != '\0') {
+               printf("Invalid mmc device '%s'; should be [0..%u]\n",
+                       argv[1], get_mmc_dev_count() - 1);
+               return CMD_RET_FAILURE;
+       }
+
+       ack = simple_strtoul(argv[2], &end, 10);
+       if (ack < 0 || ack > 1 || *end != '\0') {
+               printf("Invalid boot_ack value: %s\n", argv[2]);
+               return CMD_RET_FAILURE;
+       }
+
+       part_num = simple_strtoul(argv[3], &end, 10);
+       if (part_num < 0 || (part_num > 4 && part_num != 7) || *end != '\0') {
+               printf("Invalid part_num: %s\n", argv[3]);
+               return CMD_RET_FAILURE;
+       }
+
+       access = simple_strtoul(argv[4], &end, 10);
+       if (access < 0 || access > 7 || *end != '\0') {
+               printf("Invalid access value: %s\n", argv[4]);
+               return CMD_RET_FAILURE;
+       }
 
        mmc = init_mmc_device(dev, false);
        if (!mmc)
@@ -722,14 +803,19 @@ static int do_mmc_partconf(cmd_tbl_t *cmdtp, int flag,
        }
 
        /* acknowledge to be sent during boot operation */
-       return mmc_set_part_conf(mmc, ack, part_num, access);
+       ret = mmc_set_part_conf(mmc, ack, part_num, access);
+       if (ret)
+               printf("partconf failed: %d\n", ret);
+       return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
+
 static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
                           int argc, char * const argv[])
 {
        int dev;
        struct mmc *mmc;
        u8 enable;
+       char *end;
 
        /*
         * Set the RST_n_ENABLE bit of RST_n_FUNCTION
@@ -739,8 +825,14 @@ static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
        if (argc != 3)
                return CMD_RET_USAGE;
 
-       dev = simple_strtoul(argv[1], NULL, 10);
-       enable = simple_strtoul(argv[2], NULL, 10);
+       dev = simple_strtoul(argv[1], &end, 10);
+       if (dev < 0 || dev >= get_mmc_dev_count() || *end != '\0') {
+               printf("Invalid mmc device '%s'; should be [0..%u]\n",
+                       argv[1], get_mmc_dev_count() - 1);
+               return CMD_RET_FAILURE;
+       }
+
+       enable = simple_strtoul(argv[2], &end, 10);
 
        if (enable > 2 || enable < 0) {
                puts("Invalid RST_n_ENABLE value\n");
@@ -759,16 +851,23 @@ static int do_mmc_rst_func(cmd_tbl_t *cmdtp, int flag,
        return mmc_set_rst_n_function(mmc, enable);
 }
 #endif
+
 static int do_mmc_setdsr(cmd_tbl_t *cmdtp, int flag,
                         int argc, char * const argv[])
 {
        struct mmc *mmc;
        u32 val;
+       char *end;
        int ret;
 
        if (argc != 2)
                return CMD_RET_USAGE;
-       val = simple_strtoul(argv[2], NULL, 16);
+       val = simple_strtoul(argv[2], &end, 16);
+       if (val > 0xffff || *end != '\0') {
+               printf("Invalid DSR value '%s'; expected hex number [0..ffff]\n",
+                       argv[2]);
+               return CMD_RET_FAILURE;
+       }
 
        mmc = find_mmc_device(curr_device);
        if (!mmc) {
index 32e15c4..b03729a 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_SYS_EXTRA_OPTIONS="TX6_REV=0x2"
+CONFIG_SYS_EXTRA_OPTIONS="MMC_BOOT_SIZE=4096,TX6_REV=0x2"
 CONFIG_ARM=y
 CONFIG_SOC_MX6Q=y
 CONFIG_TARGET_TX6=y
@@ -20,8 +20,6 @@ CONFIG_NETDEVICES=y
 CONFIG_FEC_MXC=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_CMD_I2C=y
-CONFIG_NAND=y
-CONFIG_NAND_MXS=y
 CONFIG_DOS_PARTITION=y
 CONFIG_ENV_IS_IN_MMC=y
 CONFIG_FEC_MXC_PHYADDR=0
index bb73a74..d354c78 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_SYS_EXTRA_OPTIONS="TX6_REV=0x2"
+CONFIG_SYS_EXTRA_OPTIONS="MMC_BOOT_SIZE=4096,TX6_REV=0x2"
 CONFIG_ARM=y
 CONFIG_SOC_MX6Q=y
 CONFIG_TARGET_TX6=y
@@ -19,9 +19,8 @@ CONFIG_NETDEVICES=y
 CONFIG_FEC_MXC=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_CMD_I2C=y
-CONFIG_NAND=y
-CONFIG_NAND_MXS=y
 CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_MMC=y
 CONFIG_FEC_MXC_PHYADDR=0
 CONFIG_MXC_OCOTP=y
 CONFIG_CMD_FUSE=y
index 577e543..f8d3f4d 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_SYS_EXTRA_OPTIONS="TX6_REV=0x2"
+CONFIG_SYS_EXTRA_OPTIONS="MMC_BOOT_SIZE=4096,TX6_REV=0x2"
 CONFIG_ARM=y
 CONFIG_SOC_MX6Q=y
 CONFIG_TARGET_TX6=y
diff --git a/configs/tx6q-1020_sec_defconfig b/configs/tx6q-1020_sec_defconfig
new file mode 100644 (file)
index 0000000..66dc59b
--- /dev/null
@@ -0,0 +1,28 @@
+CONFIG_SYS_EXTRA_OPTIONS="MMC_BOOT_SIZE=4096,TX6_REV=0x2,SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_1020=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
+CONFIG_PHY_SMSC=y
diff --git a/configs/tx6q-10x0_sec_defconfig b/configs/tx6q-10x0_sec_defconfig
new file mode 100644 (file)
index 0000000..f3b4fd9
--- /dev/null
@@ -0,0 +1,26 @@
+CONFIG_SYS_EXTRA_OPTIONS="SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_10X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
index 4917287..8e65cbf 100644 (file)
@@ -20,8 +20,10 @@ CONFIG_NETDEVICES=y
 CONFIG_FEC_MXC=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
 CONFIG_DOS_PARTITION=y
-CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_IS_IN_NAND=y
 CONFIG_FEC_MXC_PHYADDR=0
 CONFIG_MXC_OCOTP=y
 CONFIG_CMD_FUSE=y
index 6899025..cca3102 100644 (file)
@@ -19,7 +19,10 @@ CONFIG_NETDEVICES=y
 CONFIG_FEC_MXC=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
 CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
 CONFIG_FEC_MXC_PHYADDR=0
 CONFIG_MXC_OCOTP=y
 CONFIG_CMD_FUSE=y
index 220585e..f507865 100644 (file)
@@ -14,13 +14,15 @@ CONFIG_BOOTP_DNS=y
 CONFIG_MMC=y
 CONFIG_FSL_ESDHC=y
 CONFIG_FSL_USDHC=y
-CONFIG_LCD=y
 CONFIG_NET=y
 CONFIG_NETDEVICES=y
 CONFIG_FEC_MXC=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
 CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
 CONFIG_FEC_MXC_PHYADDR=0
 CONFIG_MXC_OCOTP=y
 CONFIG_CMD_FUSE=y
diff --git a/configs/tx6s-8034_sec_defconfig b/configs/tx6s-8034_sec_defconfig
new file mode 100644 (file)
index 0000000..3462556
--- /dev/null
@@ -0,0 +1,30 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_SDRAM_BUS_WIDTH=16,SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8034=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
+CONFIG_PHY_SMSC=y
diff --git a/configs/tx6u-8012_sec_defconfig b/configs/tx6u-8012_sec_defconfig
new file mode 100644 (file)
index 0000000..4d7e3bc
--- /dev/null
@@ -0,0 +1,26 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BLOCKS=2048,SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8012=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
diff --git a/configs/tx6u-8033_sec_defconfig b/configs/tx6u-8033_sec_defconfig
new file mode 100644 (file)
index 0000000..566a155
--- /dev/null
@@ -0,0 +1,26 @@
+CONFIG_SYS_EXTRA_OPTIONS="MMC_BOOT_SIZE=1024,SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8033=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
diff --git a/configs/tx6u-80x0_sec_defconfig b/configs/tx6u-80x0_sec_defconfig
new file mode 100644 (file)
index 0000000..f1fc096
--- /dev/null
@@ -0,0 +1,26 @@
+CONFIG_SYS_EXTRA_OPTIONS="SECURE_BOOT"
+CONFIG_ARM=y
+CONFIG_SOC_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_80X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_DOS_PARTITION=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
+CONFIG_MXC_OCOTP=y
+CONFIG_CMD_FUSE=y
index d92044e..5fb86ca 100644 (file)
@@ -60,7 +60,7 @@ static int prepare_access(struct ocotp_regs **regs, u32 bank, u32 word,
        *regs = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 
        if (bank >= ARRAY_SIZE((*regs)->bank) ||
-                       word >= ARRAY_SIZE((*regs)->bank[0].fuse_regs) >> 2 ||
+                       word >= ARRAY_SIZE((*regs)->bank[0].fuse_regs) ||
                        !assert) {
                printf("mxc_ocotp %s(): Invalid argument\n", caller);
                return -EINVAL;
index 85e9509..c0bab82 100644 (file)
@@ -20,6 +20,7 @@
 
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
+static int mmc_dev_count;
 
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
@@ -1549,6 +1550,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
        INIT_LIST_HEAD(&mmc->link);
 
        list_add_tail(&mmc->link, &mmc_devices);
+       mmc_dev_count++;
 
        return mmc;
 }
@@ -1721,6 +1723,11 @@ int get_mmc_num(void)
        return cur_dev_num;
 }
 
+int get_mmc_dev_count(void)
+{
+       return mmc_dev_count;
+}
+
 void mmc_set_preinit(struct mmc *mmc, int preinit)
 {
        mmc->preinit = preinit;
@@ -1874,6 +1881,19 @@ int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
  */
 int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
 {
+       int ret;
+       ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+
+       ret = mmc_send_ext_csd(mmc, ext_csd);
+       if (ret)
+               return ret;
+
+       if (ext_csd[EXT_CSD_RST_N_FUNCTION] != 0 &&
+               ext_csd[EXT_CSD_RST_N_FUNCTION] != enable) {
+               printf("RST_N_FUNCTION is already set to %u; cannot change to %u\n",
+                       ext_csd[EXT_CSD_RST_N_FUNCTION], enable);
+               return -EINVAL;
+       }
        return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
                          enable);
 }
index e424f60..08847fd 100644 (file)
@@ -1304,12 +1304,11 @@ int board_nand_init(struct nand_chip *nand)
        struct mxs_nand_info *nand_info;
        int err;
 
-       nand_info = malloc(sizeof(struct mxs_nand_info));
+       nand_info = calloc(1, sizeof(struct mxs_nand_info));
        if (!nand_info) {
                printf("MXS NAND: Failed to allocate private data\n");
                return -ENOMEM;
        }
-       memset(nand_info, 0, sizeof(struct mxs_nand_info));
 
        err = mxs_nand_alloc_buffers(nand_info);
        if (err)
index 0c3fc74..1ae299c 100644 (file)
@@ -60,6 +60,7 @@
 #define CONFIG_SYS_SDRAM_CLK           400
 #endif
 #define CONFIG_STACKSIZE               SZ_128K
+#define CONFIG_SPL_STACK               (IRAM_BASE_ADDR + SZ_16K)
 #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)
        "cpu_clk=800\0"                                                 \
        "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
        " ${append_bootargs}\0"                                         \
+       EMMC_BOOT_PART_STR                                              \
+       EMMC_BOOT_ACK_STR                                               \
        "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
        CONFIG_SYS_FDTSAVE_CMD                                          \
        "mtdids=" MTDIDS_DEFAULT "\0"                                   \
 #endif /*  CONFIG_TX6_UBOOT_MFG */
 
 #ifdef CONFIG_TX6_NAND
-#define CONFIG_SYS_DEFAULT_BOOT_MODE "nand"
+#define CONFIG_SYS_DEFAULT_BOOT_MODE   "nand"
 #define CONFIG_SYS_BOOT_CMD_NAND                                       \
        "bootcmd_nand=set autostart no;run bootargs_ubifs;nboot linux\0"
 #define CONFIG_SYS_FDTSAVE_CMD                                         \
 #define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
 #define CONFIG_SYS_NAND_ONFI_DETECTION
 #define MMC_ROOT_STR " root=/dev/mmcblk0p2 rootwait\0"
-#define ROOTPART_UUID_STR ""
+#define ROOTPART_UUID_STR              ""
+#define EMMC_BOOT_ACK_STR              ""
+#define EMMC_BOOT_PART_STR             ""
 #else
-#define CONFIG_SYS_DEFAULT_BOOT_MODE "mmc"
-#define CONFIG_SYS_BOOT_CMD_NAND ""
+#define CONFIG_SYS_DEFAULT_BOOT_MODE   "mmc"
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
+#define CONFIG_SYS_BOOT_CMD_NAND       ""
 #define CONFIG_SYS_FDTSAVE_CMD                                         \
-       "fdtsave=mmc open 0 1;mmc write ${fdtaddr} "                    \
-       xstr(CONFIG_SYS_DTB_BLKNO) " 80;mmc close 0 1\0"
-#define MMC_ROOT_STR " root=PARTUUID=${rootpart_uuid} rootwait\0"
-#define ROOTPART_UUID_STR "rootpart_uuid=0cc66cc0-02\0"
+       "fdtsave=mmc partconf 0 ${emmc_boot_ack} ${emmc_boot_part} 1"   \
+       ";mmc write ${fdtaddr} " xstr(CONFIG_SYS_DTB_BLKNO) " 80"       \
+       ";mmc partconf 0 ${emmc_boot_ack} ${emmc_boot_part} 0\0"
 #define MTD_NAME                       ""
 #define MTDIDS_DEFAULT                 ""
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
-#endif
+#define MMC_ROOT_STR " root=PARTUUID=${rootpart_uuid} rootwait\0"
+#define ROOTPART_UUID_STR "rootpart_uuid=0cc66cc0-02\0"
+#define EMMC_BOOT_ACK_STR              "emmc_boot_ack=1\0"
+#define EMMC_BOOT_PART_STR             "emmc_boot_part="       \
+       xstr(CONFIG_SYS_MMCSD_FS_BOOT_PARTITION) "\0"
 #endif /* CONFIG_TX6_NAND */
 
 /*
 #define CONFIG_SYS_FSL_ESDHC_ADDR      0
 #endif
 #ifdef CONFIG_CMD_MMC
-#define CONFIG_DOS_PARTITION
 #define CONFIG_CMD_FAT
 #define CONFIG_FAT_WRITE
 #define CONFIG_CMD_EXT2
index 09101e2..c0bcfb9 100644 (file)
@@ -373,6 +373,7 @@ struct mmc *find_mmc_device(int dev_num);
 int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int get_mmc_num(void);
+int get_mmc_dev_count(void);
 int mmc_switch_part(int dev_num, unsigned int part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);