*
* 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;
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",
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(
);
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"
);
*/
#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;
#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
#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
*
*/
-#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 */
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
#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 */
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);
if TARGET_TX6
-config MX6
- bool
- default y
-
-config MX6Q
- bool
-
-config MX6DL
- bool
-
-config MX6QDL
- bool
-
-config MX6S
- bool
-
-config MX6SL
- bool
-
-config MX6SX
- bool
-
config SYS_BOARD
default "tx6"
config SYS_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
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
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
# 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
/*
- * 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.
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)
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)
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,
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;
}
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;
if (ret)
return ret;
+ doit = true;
for (optind = 1; optind < argc; optind++) {
char *endp;
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;
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;
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,
}
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;
}
}
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 {
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) {
}
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;
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);
} 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");
#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;
}
"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})"
);
#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>
.error "DCD too large!"
.endif
dcd_end:
+ .section ".pad"
+ .section ".text"
.endm
#define MXC_DCD_CMD_WRT(type, flags) \
#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
#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
/* 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) */
#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 */
((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))
(tODTLon << 12) | \
(tODTLoff << 4))
+ .section ".ivt"
ivt_header:
.word CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
app_start_addr:
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:
#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
#if PHYS_SDRAM_1_WIDTH == 64
#define MMDC2_MDPDC 0x021b4004
+
#define MMDC2_MPWLGCR 0x021b4808
#define MMDC2_MPWLDECTRL0 0x021b480c
#define MMDC2_MPWLDECTRL1 0x021b4810
#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
#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
#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
#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
#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
#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
#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 */
/* 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)
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: */
/* 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 */
#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))
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)
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
#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)
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
+#include "../common/karo.h"
#include "pmic.h"
#define LTC3676_BUCK1 0x01
* GNU General Public License for more details.
*
*/
-
#include <common.h>
#include <errno.h>
#include <i2c.h>
#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;
}
}
int rn5t618_pmic_setup(uchar addr);
int rn5t567_pmic_setup(uchar addr);
-int tx6_pmic_init(void);
+int tx6_pmic_init(int addr);
#include <common.h>
#include <i2c.h>
+#include "../common/karo.h"
#include "pmic.h"
#define RN5T567_NOETIMSET 0x11
#include <common.h>
#include <i2c.h>
+#include "../common/karo.h"
#include "pmic.h"
#define RN5T618_NOETIMSET 0x11
#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>
#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
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,
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", },
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;
}
#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;
#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;
{
/* 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;
}
#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)
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
.upper_margin = 2,
.vsync_len = 10,
.lower_margin = 2,
- .sync = FB_SYNC_CLK_LAT_FALL,
},
{
/* Emerging ET0500G0DH6 800 x 480 display.
*/
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);
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));
}
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);
}
{
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();
{ 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;
}
. = 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*))) }
. = ALIGN(4);
.data : {
*(.data*)
+ . = ALIGN(4);
}
- . = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
*(.__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
.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.*) }
}
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"
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")) {
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")) {
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;
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;
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;
}
}
}
+
static struct mmc *init_mmc_device(int dev, bool force_init)
{
struct mmc *mmc;
return NULL;
return mmc;
}
+
static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct mmc *mmc;
puts("Authentication key programming aborted\n");
return 0;
}
+
static int do_mmcrpmb_key(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
}
return CMD_RET_SUCCESS;
}
+
static int do_mmcrpmb_read(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
+
static int do_mmcrpmb_write(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
+
static int do_mmcrpmb_counter(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
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[])
{
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[])
{
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[])
{
return CMD_RET_SUCCESS;
}
+
static int do_mmc_part(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
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[])
{
return CMD_RET_SUCCESS;
}
+
static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
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");
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;
}
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)
}
/* 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
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");
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) {
-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
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_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
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
-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
--- /dev/null
+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
--- /dev/null
+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
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
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_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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
*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;
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)
{
INIT_LIST_HEAD(&mmc->link);
list_add_tail(&mmc->link, &mmc_devices);
+ mmc_dev_count++;
return mmc;
}
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;
*/
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);
}
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)
#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
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);