From: Lothar Waßmann Date: Fri, 21 Aug 2015 14:51:29 +0000 (+0200) Subject: Merge remote-tracking branch 'remotes/tx6/tx6' into karo-tx-uboot X-Git-Tag: KARO-TX6-2015-09-18~4034^2 X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=commitdiff_plain;h=e5bfa321e40ee65bbcfee24f6b9456609ed6ba83;hp=ea558300de20bfb9713a6a8f54ed875172da2e51 Merge remote-tracking branch 'remotes/tx6/tx6' into karo-tx-uboot --- diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c index 8dee595eaf..757096d356 100644 --- a/arch/arm/cpu/armv7/mx6/hab.c +++ b/arch/arm/cpu/armv7/mx6/hab.c @@ -3,78 +3,42 @@ * * SPDX-License-Identifier: GPL-2.0+ */ - #include #include #include -#include #include #include +#include -/* -------- 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 @@ -111,18 +75,30 @@ * +------------+ + 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" ); diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 223cdc207f..63d50c1abd 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -8,6 +8,11 @@ */ #include +#include +#include +#include +#include +#include #include #include #include @@ -17,17 +22,10 @@ #include #include #include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h index 261a7b38d0..ce465c6179 100644 --- a/arch/arm/include/asm/arch-mx6/crm_regs.h +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h @@ -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 diff --git a/arch/arm/include/asm/arch-mx6/hab.h b/arch/arm/include/asm/arch-mx6/hab.h index 230be45204..e85651632e 100644 --- a/arch/arm/include/asm/arch-mx6/hab.h +++ b/arch/arm/include/asm/arch-mx6/hab.h @@ -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 +#include + +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 */ diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index bc1c58a7b1..6fbc4412ac 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -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); diff --git a/board/karo/tx6/Kconfig b/board/karo/tx6/Kconfig index c848d59d11..091efde26c 100644 --- a/board/karo/tx6/Kconfig +++ b/board/karo/tx6/Kconfig @@ -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 diff --git a/board/karo/tx6/config.mk b/board/karo/tx6/config.mk index 9f156bc849..acb0cd0d51 100644 --- a/board/karo/tx6/config.mk +++ b/board/karo/tx6/config.mk @@ -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 diff --git a/board/karo/tx6/flash.c b/board/karo/tx6/flash.c index d0bb7c858f..d57c994707 100644 --- a/board/karo/tx6/flash.c +++ b/board/karo/tx6/flash.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2014 Lothar Waßmann + * Copyright (C) 2012-2015 Lothar Waßmann * * 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 {|block#}] [-r [{|block#}]] [-e #] [
] []\n" "\t-f \twrite bootloader image to partition \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 \twrite redundant bootloader image to partition \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
\tRAM address of bootloader image (default: ${fileaddr}\n" - "\t\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
\tRAM address of bootloader image (default: ${fileaddr})\n" + "\t\tlength of bootloader image in RAM (default: ${filesize})" ); diff --git a/board/karo/tx6/lowlevel_init.S b/board/karo/tx6/lowlevel_init.S index 16f78d3a5a..561a1d1457 100644 --- a/board/karo/tx6/lowlevel_init.S +++ b/board/karo/tx6/lowlevel_init.S @@ -1,5 +1,7 @@ #include +#include #include +#include #include #include @@ -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) diff --git a/board/karo/tx6/ltc3676.c b/board/karo/tx6/ltc3676.c index 53cf5e2382..3f692d3fd6 100644 --- a/board/karo/tx6/ltc3676.c +++ b/board/karo/tx6/ltc3676.c @@ -20,6 +20,7 @@ #include #include +#include "../common/karo.h" #include "pmic.h" #define LTC3676_BUCK1 0x01 diff --git a/board/karo/tx6/pmic.c b/board/karo/tx6/pmic.c index 2743dadd32..a29a74bd17 100644 --- a/board/karo/tx6/pmic.c +++ b/board/karo/tx6/pmic.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. * */ - #include #include #include @@ -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; } } diff --git a/board/karo/tx6/pmic.h b/board/karo/tx6/pmic.h index 4786eefc9b..1b301b7c4a 100644 --- a/board/karo/tx6/pmic.h +++ b/board/karo/tx6/pmic.h @@ -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); diff --git a/board/karo/tx6/rn5t567.c b/board/karo/tx6/rn5t567.c index 6f791374b4..913dd2c274 100644 --- a/board/karo/tx6/rn5t567.c +++ b/board/karo/tx6/rn5t567.c @@ -18,6 +18,7 @@ #include #include +#include "../common/karo.h" #include "pmic.h" #define RN5T567_NOETIMSET 0x11 diff --git a/board/karo/tx6/rn5t618.c b/board/karo/tx6/rn5t618.c index 19aba871af..8737e767f0 100644 --- a/board/karo/tx6/rn5t618.c +++ b/board/karo/tx6/rn5t618.c @@ -18,6 +18,7 @@ #include #include +#include "../common/karo.h" #include "pmic.h" #define RN5T618_NOETIMSET 0x11 diff --git a/board/karo/tx6/tx6qdl.c b/board/karo/tx6/tx6qdl.c index 15340db196..1d09de4ac6 100644 --- a/board/karo/tx6/tx6qdl.c +++ b/board/karo/tx6/tx6qdl.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/board/karo/tx6/u-boot.lds b/board/karo/tx6/u-boot.lds index 4578febfb4..c4e0e2158c 100644 --- a/board/karo/tx6/u-boot.lds +++ b/board/karo/tx6/u-boot.lds @@ -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.*) } } diff --git a/common/Kconfig b/common/Kconfig index ead783c184..da18c7ae77 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -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" diff --git a/common/cmd_fuse.c b/common/cmd_fuse.c index d4bc0f6c94..4d4f77a72d 100644 --- a/common/cmd_fuse.c +++ b/common/cmd_fuse.c @@ -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; diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index c89782ab4b..f9378de44a 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -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) { diff --git a/configs/tx6q-1020_defconfig b/configs/tx6q-1020_defconfig index 32e15c4ec4..b03729a19c 100644 --- a/configs/tx6q-1020_defconfig +++ b/configs/tx6q-1020_defconfig @@ -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 diff --git a/configs/tx6q-1020_mfg_defconfig b/configs/tx6q-1020_mfg_defconfig index bb73a743c5..d354c782d0 100644 --- a/configs/tx6q-1020_mfg_defconfig +++ b/configs/tx6q-1020_mfg_defconfig @@ -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 diff --git a/configs/tx6q-1020_noenv_defconfig b/configs/tx6q-1020_noenv_defconfig index 577e54317a..f8d3f4d81e 100644 --- a/configs/tx6q-1020_noenv_defconfig +++ b/configs/tx6q-1020_noenv_defconfig @@ -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 index 0000000000..66dc59b180 --- /dev/null +++ b/configs/tx6q-1020_sec_defconfig @@ -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 index 0000000000..f3b4fd9b7f --- /dev/null +++ b/configs/tx6q-10x0_sec_defconfig @@ -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 diff --git a/configs/tx6s-8034_defconfig b/configs/tx6s-8034_defconfig index 4917287bf4..8e65cbf0d0 100644 --- a/configs/tx6s-8034_defconfig +++ b/configs/tx6s-8034_defconfig @@ -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 diff --git a/configs/tx6s-8034_mfg_defconfig b/configs/tx6s-8034_mfg_defconfig index 6899025f90..cca3102919 100644 --- a/configs/tx6s-8034_mfg_defconfig +++ b/configs/tx6s-8034_mfg_defconfig @@ -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 diff --git a/configs/tx6s-8034_noenv_defconfig b/configs/tx6s-8034_noenv_defconfig index 220585e74b..f5078658cf 100644 --- a/configs/tx6s-8034_noenv_defconfig +++ b/configs/tx6s-8034_noenv_defconfig @@ -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 index 0000000000..3462556905 --- /dev/null +++ b/configs/tx6s-8034_sec_defconfig @@ -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 index 0000000000..4d7e3bcf3e --- /dev/null +++ b/configs/tx6u-8012_sec_defconfig @@ -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 index 0000000000..566a1551bb --- /dev/null +++ b/configs/tx6u-8033_sec_defconfig @@ -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 index 0000000000..f1fc096022 --- /dev/null +++ b/configs/tx6u-80x0_sec_defconfig @@ -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 diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c index d92044eeda..5fb86ca6b2 100644 --- a/drivers/misc/mxc_ocotp.c +++ b/drivers/misc/mxc_ocotp.c @@ -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; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 85e9509ed1..c0bab82714 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -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); } diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c index e424f60a9a..08847fd8e2 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -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) diff --git a/include/configs/tx6.h b/include/configs/tx6.h index 0c3fc74a61..1ae299c2cc 100644 --- a/include/configs/tx6.h +++ b/include/configs/tx6.h @@ -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) @@ -172,6 +173,8 @@ "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" \ @@ -185,7 +188,7 @@ #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 \ @@ -195,19 +198,24 @@ #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 */ /* @@ -299,7 +307,6 @@ #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 diff --git a/include/mmc.h b/include/mmc.h index 09101e2c87..c0bcfb9076 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -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);