Commit b03fe7950619f3ea503db51173f65bb418c06cc8
1 parent
0ec2a01911
Exists in
smarc-rel_imx_4.1.15_2.0.0_ga
Initial Commit for SMARC-FiMX7 Solo and Dual Core modules
Showing 41 changed files with 4689 additions and 6 deletions Side-by-side Diff
- arch/arm/cpu/armv7/mx7/Kconfig
- arch/arm/cpu/armv7/mx7/soc.c
- arch/arm/imx-common/cpu.c
- arch/arm/include/asm/arch-imx/cpu.h
- arch/arm/include/asm/arch-mx7/imx-rdc.h
- arch/arm/include/asm/arch-mx7/imx-regs.h
- arch/arm/include/asm/arch-mx7/mx7-pins.h
- board/embedian/common/Makefile
- board/embedian/common/arm_sleep.c
- board/embedian/common/cmd_esbc_validate.c
- board/embedian/common/eeprom.h
- board/embedian/common/fsl_chain_of_trust.c
- board/embedian/common/fsl_validate.c
- board/embedian/common/mmc.c
- board/embedian/common/recovery.c
- board/embedian/common/sdhc_boot.c
- board/embedian/common/sleep.h
- board/embedian/common/sys_eeprom.c
- board/embedian/smarcfimx7/Kconfig
- board/embedian/smarcfimx7/MAINTAINERS
- board/embedian/smarcfimx7/Makefile
- board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg
- board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg
- board/embedian/smarcfimx7/pfuze.h
- board/embedian/smarcfimx7/plugin.S
- board/embedian/smarcfimx7/smarcfimx7.c
- board/embedian/smarcfimx7/smarcfimx7.h
- common/autoboot.c
- configs/smarcfimx7d_ser0_defconfig
- configs/smarcfimx7d_ser1_defconfig
- configs/smarcfimx7d_ser2_defconfig
- configs/smarcfimx7d_ser3_defconfig
- configs/smarcfimx7s_ser0_defconfig
- configs/smarcfimx7s_ser1_defconfig
- configs/smarcfimx7s_ser2_defconfig
- configs/smarcfimx7s_ser3_defconfig
- drivers/mtd/spi/sf_params.c
- drivers/spi/fsl_qspi.c
- include/config_distro_defaults.h
- include/configs/mx7smarc_common.h
- include/configs/smarcfimx7.h
arch/arm/cpu/armv7/mx7/Kconfig
... | ... | @@ -18,6 +18,11 @@ |
18 | 18 | select DM |
19 | 19 | select DM_THERMAL |
20 | 20 | |
21 | +config TARGET_SMARCFIMX7 | |
22 | + bool "smarcfimx7" | |
23 | + select DM | |
24 | + select DM_THERMAL | |
25 | + | |
21 | 26 | config TARGET_MX7D_12X12_LPDDR3_ARM2 |
22 | 27 | bool "mx7d_12x12_lpddr3_arm2" |
23 | 28 | select MX7D |
... | ... | @@ -54,6 +59,7 @@ |
54 | 59 | default "mx7" |
55 | 60 | |
56 | 61 | source "board/freescale/mx7dsabresd/Kconfig" |
62 | +source "board/embedian/smarcfimx7/Kconfig" | |
57 | 63 | source "board/freescale/mx7d_12x12_lpddr3_arm2/Kconfig" |
58 | 64 | source "board/freescale/mx7d_12x12_ddr3_arm2/Kconfig" |
59 | 65 | source "board/freescale/mx7d_19x19_lpddr3_arm2/Kconfig" |
arch/arm/cpu/armv7/mx7/soc.c
... | ... | @@ -170,12 +170,30 @@ |
170 | 170 | return val; |
171 | 171 | } |
172 | 172 | |
173 | +static bool is_mx7d(void) | |
174 | +{ | |
175 | + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; | |
176 | + struct fuse_bank *bank = &ocotp->bank[1]; | |
177 | + struct fuse_bank1_regs *fuse = | |
178 | + (struct fuse_bank1_regs *)bank->fuse_regs; | |
179 | + int val; | |
180 | + | |
181 | + val = readl(&fuse->tester4); | |
182 | + if (val & 1) | |
183 | + return false; | |
184 | + else | |
185 | + return true; | |
186 | +} | |
187 | + | |
173 | 188 | u32 get_cpu_rev(void) |
174 | 189 | { |
175 | 190 | struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) |
176 | 191 | ANATOP_BASE_ADDR; |
177 | 192 | u32 reg = readl(&ccm_anatop->digprog); |
178 | 193 | u32 type = (reg >> 16) & 0xff; |
194 | + | |
195 | + if (!is_mx7d()) | |
196 | + type = MXC_CPU_MX7S; | |
179 | 197 | |
180 | 198 | reg &= 0xff; |
181 | 199 | return (type << 12) | reg; |
arch/arm/imx-common/cpu.c
... | ... | @@ -141,6 +141,8 @@ |
141 | 141 | const char *get_imx_type(u32 imxtype) |
142 | 142 | { |
143 | 143 | switch (imxtype) { |
144 | + case MXC_CPU_MX7S: | |
145 | + return "7S"; /* Single-core version of the mx7 */ | |
144 | 146 | case MXC_CPU_MX7D: |
145 | 147 | return "7D"; /* Dual-core version of the mx7 */ |
146 | 148 | case MXC_CPU_MX6QP: |
arch/arm/include/asm/arch-imx/cpu.h
arch/arm/include/asm/arch-mx7/imx-rdc.h
arch/arm/include/asm/arch-mx7/imx-regs.h
... | ... | @@ -1009,6 +1009,23 @@ |
1009 | 1009 | u16 wmcr; /* Miscellaneous Control */ |
1010 | 1010 | }; |
1011 | 1011 | |
1012 | +#define PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) | |
1013 | +#define PWMCR_DOZEEN (1 << 24) | |
1014 | +#define PWMCR_WAITEN (1 << 23) | |
1015 | +#define PWMCR_DBGEN (1 << 22) | |
1016 | +#define PWMCR_CLKSRC_IPG_HIGH (2 << 16) | |
1017 | +#define PWMCR_CLKSRC_IPG (1 << 16) | |
1018 | +#define PWMCR_EN (1 << 0) | |
1019 | + | |
1020 | +struct pwm_regs { | |
1021 | + u32 cr; | |
1022 | + u32 sr; | |
1023 | + u32 ir; | |
1024 | + u32 sar; | |
1025 | + u32 pr; | |
1026 | + u32 cnr; | |
1027 | +}; | |
1028 | + | |
1012 | 1029 | struct dbg_monitor_regs { |
1013 | 1030 | u32 ctrl[4]; /* Control */ |
1014 | 1031 | u32 master_en[4]; /* Master enable */ |
arch/arm/include/asm/arch-mx7/mx7-pins.h
board/embedian/common/Makefile
1 | +# | |
2 | +# (C) Copyright 2006 | |
3 | +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | +# | |
5 | +# SPDX-License-Identifier: GPL-2.0+ | |
6 | +# | |
7 | + | |
8 | +ifndef CONFIG_SPL_BUILD | |
9 | +obj-$(CONFIG_ID_EEPROM) += sys_eeprom.o | |
10 | +endif | |
11 | + | |
12 | +ifdef CONFIG_ARM | |
13 | +obj-$(CONFIG_DEEP_SLEEP) += arm_sleep.o | |
14 | +endif | |
15 | + | |
16 | +obj-y += mmc.o | |
17 | +ifdef CONFIG_FSL_FASTBOOT | |
18 | +obj-${CONFIG_ANDROID_RECOVERY} += recovery.o | |
19 | +endif | |
20 | + | |
21 | +ifdef CONFIG_SECURE_BOOT | |
22 | +obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o | |
23 | +endif | |
24 | +obj-$(CONFIG_CHAIN_OF_TRUST) += fsl_chain_of_trust.o |
board/embedian/common/arm_sleep.c
1 | +/* | |
2 | + * Copyright 2014 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <asm/io.h> | |
9 | +#ifndef CONFIG_ARMV7_NONSEC | |
10 | +#error " Deep sleep needs non-secure mode support. " | |
11 | +#else | |
12 | +#include <asm/secure.h> | |
13 | +#endif | |
14 | +#include <asm/armv7.h> | |
15 | + | |
16 | +#if defined(CONFIG_LS102XA) | |
17 | +#include <asm/arch/immap_ls102xa.h> | |
18 | +#endif | |
19 | + | |
20 | +#include "sleep.h" | |
21 | +#ifdef CONFIG_U_QE | |
22 | +#include <fsl_qe.h> | |
23 | +#endif | |
24 | + | |
25 | +DECLARE_GLOBAL_DATA_PTR; | |
26 | + | |
27 | +void __weak board_mem_sleep_setup(void) | |
28 | +{ | |
29 | +} | |
30 | + | |
31 | +void __weak board_sleep_prepare(void) | |
32 | +{ | |
33 | +} | |
34 | + | |
35 | +bool is_warm_boot(void) | |
36 | +{ | |
37 | + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; | |
38 | + | |
39 | + if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR) | |
40 | + return 1; | |
41 | + | |
42 | + return 0; | |
43 | +} | |
44 | + | |
45 | +void fsl_dp_disable_console(void) | |
46 | +{ | |
47 | + gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; | |
48 | +} | |
49 | + | |
50 | +/* | |
51 | + * When wakeup from deep sleep, the first 128 bytes space | |
52 | + * will be used to do DDR training which corrupts the data | |
53 | + * in there. This function will restore them. | |
54 | + */ | |
55 | +static void dp_ddr_restore(void) | |
56 | +{ | |
57 | + u64 *src, *dst; | |
58 | + int i; | |
59 | + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; | |
60 | + | |
61 | + /* get the address of ddr date from SPARECR3 */ | |
62 | + src = (u64 *)in_le32(&scfg->sparecr[2]); | |
63 | + dst = (u64 *)CONFIG_SYS_SDRAM_BASE; | |
64 | + | |
65 | + for (i = 0; i < DDR_BUFF_LEN / 8; i++) | |
66 | + *dst++ = *src++; | |
67 | +} | |
68 | + | |
69 | +static void dp_resume_prepare(void) | |
70 | +{ | |
71 | + dp_ddr_restore(); | |
72 | + board_sleep_prepare(); | |
73 | + armv7_init_nonsec(); | |
74 | +#ifdef CONFIG_U_QE | |
75 | + u_qe_resume(); | |
76 | +#endif | |
77 | +} | |
78 | + | |
79 | +int fsl_dp_resume(void) | |
80 | +{ | |
81 | + u32 start_addr; | |
82 | + void (*kernel_resume)(void); | |
83 | + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; | |
84 | + | |
85 | + if (!is_warm_boot()) | |
86 | + return 0; | |
87 | + | |
88 | + dp_resume_prepare(); | |
89 | + | |
90 | + /* Get the entry address and jump to kernel */ | |
91 | + start_addr = in_le32(&scfg->sparecr[1]); | |
92 | + debug("Entry address is 0x%08x\n", start_addr); | |
93 | + kernel_resume = (void (*)(void))start_addr; | |
94 | + secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0); | |
95 | + | |
96 | + return 0; | |
97 | +} |
board/embedian/common/cmd_esbc_validate.c
1 | +/* | |
2 | + * Copyright 2015 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <command.h> | |
9 | +#include <fsl_validate.h> | |
10 | + | |
11 | +static int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc, | |
12 | + char * const argv[]) | |
13 | +{ | |
14 | + if (fsl_check_boot_mode_secure() == 0) { | |
15 | + printf("Boot Mode is Non-Secure. Not entering spin loop.\n"); | |
16 | + return 0; | |
17 | + } | |
18 | + | |
19 | + printf("Core is entering spin loop.\n"); | |
20 | +loop: | |
21 | + goto loop; | |
22 | + | |
23 | + return 0; | |
24 | +} | |
25 | + | |
26 | +static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, | |
27 | + char * const argv[]) | |
28 | +{ | |
29 | + char *hash_str = NULL; | |
30 | + uintptr_t haddr; | |
31 | + int ret; | |
32 | + | |
33 | + if (argc < 2) | |
34 | + return cmd_usage(cmdtp); | |
35 | + else if (argc > 2) | |
36 | + /* Second arg - Optional - Hash Str*/ | |
37 | + hash_str = argv[2]; | |
38 | + | |
39 | + /* First argument - header address -32/64bit */ | |
40 | + haddr = (uintptr_t)simple_strtoul(argv[1], NULL, 16); | |
41 | + | |
42 | + /* With esbc_validate command, Image address must be | |
43 | + * part of header. So, the function is called | |
44 | + * by passing this argument as 0. | |
45 | + */ | |
46 | + ret = fsl_secboot_validate(haddr, hash_str, 0); | |
47 | + if (ret) | |
48 | + return 1; | |
49 | + | |
50 | + printf("esbc_validate command successful\n"); | |
51 | + return 0; | |
52 | +} | |
53 | + | |
54 | +/***************************************************/ | |
55 | +static char esbc_validate_help_text[] = | |
56 | + "esbc_validate hdr_addr <hash_val> - Validates signature using\n" | |
57 | + " RSA verification\n" | |
58 | + " $hdr_addr Address of header of the image\n" | |
59 | + " to be validated.\n" | |
60 | + " $hash_val -Optional\n" | |
61 | + " It provides Hash of public/srk key to be\n" | |
62 | + " used to verify signature.\n"; | |
63 | + | |
64 | +U_BOOT_CMD( | |
65 | + esbc_validate, 3, 0, do_esbc_validate, | |
66 | + "Validates signature on a given image using RSA verification", | |
67 | + esbc_validate_help_text | |
68 | +); | |
69 | + | |
70 | +U_BOOT_CMD( | |
71 | + esbc_halt, 1, 0, do_esbc_halt, | |
72 | + "Put the core in spin loop (Secure Boot Only)", | |
73 | + "" | |
74 | +); |
board/embedian/common/eeprom.h
1 | +/* | |
2 | + * Copyright 2004 Freescale Semiconductor. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#ifndef __EEPROM_H_ | |
8 | +#define __EEPROM_H_ | |
9 | + | |
10 | + | |
11 | +/* | |
12 | + * EEPROM Board System Register interface. | |
13 | + */ | |
14 | + | |
15 | + | |
16 | +/* | |
17 | + * CPU Board Revision | |
18 | + */ | |
19 | +#define MPC85XX_CPU_BOARD_REV(maj, min) ((((maj)&0xff) << 8) | ((min) & 0xff)) | |
20 | +#define MPC85XX_CPU_BOARD_MAJOR(rev) (((rev) >> 8) & 0xff) | |
21 | +#define MPC85XX_CPU_BOARD_MINOR(rev) ((rev) & 0xff) | |
22 | + | |
23 | +#define MPC85XX_CPU_BOARD_REV_UNKNOWN MPC85XX_CPU_BOARD_REV(0,0) | |
24 | +#define MPC85XX_CPU_BOARD_REV_1_0 MPC85XX_CPU_BOARD_REV(1,0) | |
25 | +#define MPC85XX_CPU_BOARD_REV_1_1 MPC85XX_CPU_BOARD_REV(1,1) | |
26 | + | |
27 | +/* | |
28 | + * Returns CPU board revision register as a 16-bit value with | |
29 | + * the Major in the high byte, and Minor in the low byte. | |
30 | + */ | |
31 | +extern unsigned int get_cpu_board_revision(void); | |
32 | + | |
33 | + | |
34 | +#endif /* __CADMUS_H_ */ |
board/embedian/common/fsl_chain_of_trust.c
1 | +/* | |
2 | + * Copyright 2015 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <fsl_validate.h> | |
9 | +#include <fsl_sfp.h> | |
10 | + | |
11 | +#ifdef CONFIG_LS102XA | |
12 | +#include <asm/arch/immap_ls102xa.h> | |
13 | +#endif | |
14 | + | |
15 | +#if defined(CONFIG_MPC85xx) | |
16 | +#define CONFIG_DCFG_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR | |
17 | +#else | |
18 | +#define CONFIG_DCFG_ADDR CONFIG_SYS_FSL_GUTS_ADDR | |
19 | +#endif | |
20 | + | |
21 | +#ifdef CONFIG_SYS_FSL_CCSR_GUR_LE | |
22 | +#define gur_in32(a) in_le32(a) | |
23 | +#else | |
24 | +#define gur_in32(a) in_be32(a) | |
25 | +#endif | |
26 | + | |
27 | +/* Check the Boot Mode. If Secure, return 1 else return 0 */ | |
28 | +int fsl_check_boot_mode_secure(void) | |
29 | +{ | |
30 | + uint32_t val; | |
31 | + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); | |
32 | + struct ccsr_gur __iomem *gur = (void *)(CONFIG_DCFG_ADDR); | |
33 | + | |
34 | + val = sfp_in32(&sfp_regs->ospr) & ITS_MASK; | |
35 | + if (val == ITS_MASK) | |
36 | + return 1; | |
37 | + | |
38 | +#if defined(CONFIG_FSL_CORENET) || !defined(CONFIG_MPC85xx) | |
39 | + /* For PBL based platforms check the SB_EN bit in RCWSR */ | |
40 | + val = gur_in32(&gur->rcwsr[RCW_SB_EN_REG_INDEX - 1]) & RCW_SB_EN_MASK; | |
41 | + if (val == RCW_SB_EN_MASK) | |
42 | + return 1; | |
43 | +#endif | |
44 | + | |
45 | +#if defined(CONFIG_MPC85xx) && !defined(CONFIG_FSL_CORENET) | |
46 | + /* For Non-PBL Platforms, check the Device Status register 2*/ | |
47 | + val = gur_in32(&gur->pordevsr2) & MPC85xx_PORDEVSR2_SBC_MASK; | |
48 | + if (val != MPC85xx_PORDEVSR2_SBC_MASK) | |
49 | + return 1; | |
50 | + | |
51 | +#endif | |
52 | + return 0; | |
53 | +} | |
54 | + | |
55 | +int fsl_setenv_chain_of_trust(void) | |
56 | +{ | |
57 | + /* Check Boot Mode | |
58 | + * If Boot Mode is Non-Secure, no changes are required | |
59 | + */ | |
60 | + if (fsl_check_boot_mode_secure() == 0) | |
61 | + return 0; | |
62 | + | |
63 | + /* If Boot mode is Secure, set the environment variables | |
64 | + * bootdelay = 0 (To disable Boot Prompt) | |
65 | + * bootcmd = CONFIG_CHAIN_BOOT_CMD (Validate and execute Boot script) | |
66 | + */ | |
67 | + setenv("bootdelay", "0"); | |
68 | + setenv("bootcmd", CONFIG_CHAIN_BOOT_CMD); | |
69 | + return 0; | |
70 | +} |
board/embedian/common/fsl_validate.c
1 | +/* | |
2 | + * Copyright 2015 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <fsl_validate.h> | |
9 | +#include <fsl_secboot_err.h> | |
10 | +#include <fsl_sfp.h> | |
11 | +#include <fsl_sec.h> | |
12 | +#include <command.h> | |
13 | +#include <malloc.h> | |
14 | +#include <dm/uclass.h> | |
15 | +#include <u-boot/rsa-mod-exp.h> | |
16 | +#include <hash.h> | |
17 | +#include <fsl_secboot_err.h> | |
18 | +#ifdef CONFIG_LS102XA | |
19 | +#include <asm/arch/immap_ls102xa.h> | |
20 | +#endif | |
21 | + | |
22 | +#define SHA256_BITS 256 | |
23 | +#define SHA256_BYTES (256/8) | |
24 | +#define SHA256_NIBBLES (256/4) | |
25 | +#define NUM_HEX_CHARS (sizeof(ulong) * 2) | |
26 | + | |
27 | +#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \ | |
28 | + ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \ | |
29 | + ((key_len) == 2 * KEY_SIZE_BYTES)) | |
30 | + | |
31 | +/* This array contains DER value for SHA-256 */ | |
32 | +static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, | |
33 | + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, | |
34 | + 0x04, 0x20 | |
35 | + }; | |
36 | + | |
37 | +static u8 hash_val[SHA256_BYTES]; | |
38 | +static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; | |
39 | + | |
40 | +void branch_to_self(void) __attribute__ ((noreturn)); | |
41 | + | |
42 | +/* | |
43 | + * This function will put core in infinite loop. | |
44 | + * This will be called when the ESBC can not proceed further due | |
45 | + * to some unknown errors. | |
46 | + */ | |
47 | +void branch_to_self(void) | |
48 | +{ | |
49 | + printf("Core is in infinite loop due to errors.\n"); | |
50 | +self: | |
51 | + goto self; | |
52 | +} | |
53 | + | |
54 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
55 | +static u32 check_ie(struct fsl_secboot_img_priv *img) | |
56 | +{ | |
57 | + if (img->hdr.ie_flag) | |
58 | + return 1; | |
59 | + | |
60 | + return 0; | |
61 | +} | |
62 | + | |
63 | +/* This function returns the CSF Header Address of uboot | |
64 | + * For MPC85xx based platforms, the LAW mapping for NOR | |
65 | + * flash changes in uboot code. Hence the offset needs | |
66 | + * to be calculated and added to the new NOR flash base | |
67 | + * address | |
68 | + */ | |
69 | +#if defined(CONFIG_MPC85xx) | |
70 | +int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) | |
71 | +{ | |
72 | + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
73 | + u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); | |
74 | + u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE); | |
75 | + u32 flash_addr, addr; | |
76 | + int found = 0; | |
77 | + int i = 0; | |
78 | + | |
79 | + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { | |
80 | + flash_addr = flash_info[i].start[0]; | |
81 | + addr = flash_info[i].start[0] + csf_flash_offset; | |
82 | + if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) { | |
83 | + debug("Barker found on addr %x\n", addr); | |
84 | + found = 1; | |
85 | + break; | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + if (!found) | |
90 | + return -1; | |
91 | + | |
92 | + *csf_addr = addr; | |
93 | + *flash_base_addr = flash_addr; | |
94 | + | |
95 | + return 0; | |
96 | +} | |
97 | +#else | |
98 | +/* For platforms like LS1020, correct flash address is present in | |
99 | + * the header. So the function reqturns flash base address as 0 | |
100 | + */ | |
101 | +int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) | |
102 | +{ | |
103 | + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); | |
104 | + u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); | |
105 | + | |
106 | + if (memcmp((u8 *)(uintptr_t)csf_hdr_addr, | |
107 | + barker_code, ESBC_BARKER_LEN)) | |
108 | + return -1; | |
109 | + | |
110 | + *csf_addr = csf_hdr_addr; | |
111 | + *flash_base_addr = 0; | |
112 | + return 0; | |
113 | +} | |
114 | +#endif | |
115 | + | |
116 | +static int get_ie_info_addr(u32 *ie_addr) | |
117 | +{ | |
118 | + struct fsl_secboot_img_hdr *hdr; | |
119 | + struct fsl_secboot_sg_table *sg_tbl; | |
120 | + u32 flash_base_addr, csf_addr; | |
121 | + | |
122 | + if (get_csf_base_addr(&csf_addr, &flash_base_addr)) | |
123 | + return -1; | |
124 | + | |
125 | + hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr; | |
126 | + | |
127 | + /* For SoC's with Trust Architecture v1 with corenet bus | |
128 | + * the sg table field in CSF header has absolute address | |
129 | + * for sg table in memory. In other Trust Architecture, | |
130 | + * this field specifies the offset of sg table from the | |
131 | + * base address of CSF Header | |
132 | + */ | |
133 | +#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET) | |
134 | + sg_tbl = (struct fsl_secboot_sg_table *) | |
135 | + (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) + | |
136 | + flash_base_addr); | |
137 | +#else | |
138 | + sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr + | |
139 | + (u32)hdr->psgtable); | |
140 | +#endif | |
141 | + | |
142 | + /* IE Key Table is the first entry in the SG Table */ | |
143 | +#if defined(CONFIG_MPC85xx) | |
144 | + *ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) + | |
145 | + flash_base_addr; | |
146 | +#else | |
147 | + *ie_addr = sg_tbl->src_addr; | |
148 | +#endif | |
149 | + | |
150 | + debug("IE Table address is %x\n", *ie_addr); | |
151 | + return 0; | |
152 | +} | |
153 | + | |
154 | +#endif | |
155 | + | |
156 | +#ifdef CONFIG_KEY_REVOCATION | |
157 | +/* This function checks srk_table_flag in header and set/reset srk_flag.*/ | |
158 | +static u32 check_srk(struct fsl_secboot_img_priv *img) | |
159 | +{ | |
160 | + if (img->hdr.len_kr.srk_table_flag & SRK_FLAG) | |
161 | + return 1; | |
162 | + | |
163 | + return 0; | |
164 | +} | |
165 | + | |
166 | +/* This function returns ospr's key_revoc values.*/ | |
167 | +static u32 get_key_revoc(void) | |
168 | +{ | |
169 | + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); | |
170 | + return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >> | |
171 | + OSPR_KEY_REVOC_SHIFT; | |
172 | +} | |
173 | + | |
174 | +/* This function checks if selected key is revoked or not.*/ | |
175 | +static u32 is_key_revoked(u32 keynum, u32 rev_flag) | |
176 | +{ | |
177 | + if (keynum == UNREVOCABLE_KEY) | |
178 | + return 0; | |
179 | + | |
180 | + if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag) | |
181 | + return 1; | |
182 | + | |
183 | + return 0; | |
184 | +} | |
185 | + | |
186 | +/* It read validates srk_table key lengths.*/ | |
187 | +static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img) | |
188 | +{ | |
189 | + int i = 0; | |
190 | + u32 ret, key_num, key_revoc_flag, size; | |
191 | + struct fsl_secboot_img_hdr *hdr = &img->hdr; | |
192 | + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; | |
193 | + | |
194 | + if ((hdr->len_kr.num_srk == 0) || | |
195 | + (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) | |
196 | + return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; | |
197 | + | |
198 | + key_num = hdr->len_kr.srk_sel; | |
199 | + if (key_num == 0 || key_num > hdr->len_kr.num_srk) | |
200 | + return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; | |
201 | + | |
202 | + /* Get revoc key from sfp */ | |
203 | + key_revoc_flag = get_key_revoc(); | |
204 | + ret = is_key_revoked(key_num, key_revoc_flag); | |
205 | + if (ret) | |
206 | + return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; | |
207 | + | |
208 | + size = hdr->len_kr.num_srk * sizeof(struct srk_table); | |
209 | + | |
210 | + memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); | |
211 | + | |
212 | + for (i = 0; i < hdr->len_kr.num_srk; i++) { | |
213 | + if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len)) | |
214 | + return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN; | |
215 | + } | |
216 | + | |
217 | + img->key_len = img->srk_tbl[key_num - 1].key_len; | |
218 | + | |
219 | + memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), | |
220 | + img->key_len); | |
221 | + | |
222 | + return 0; | |
223 | +} | |
224 | +#endif | |
225 | + | |
226 | +static u32 read_validate_single_key(struct fsl_secboot_img_priv *img) | |
227 | +{ | |
228 | + struct fsl_secboot_img_hdr *hdr = &img->hdr; | |
229 | + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; | |
230 | + | |
231 | + /* check key length */ | |
232 | + if (!CHECK_KEY_LEN(hdr->key_len)) | |
233 | + return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; | |
234 | + | |
235 | + memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); | |
236 | + | |
237 | + img->key_len = hdr->key_len; | |
238 | + | |
239 | + return 0; | |
240 | +} | |
241 | + | |
242 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
243 | +static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img) | |
244 | +{ | |
245 | + struct fsl_secboot_img_hdr *hdr = &img->hdr; | |
246 | + u32 ie_key_len, ie_revoc_flag, ie_num; | |
247 | + struct ie_key_info *ie_info; | |
248 | + | |
249 | + if (get_ie_info_addr(&img->ie_addr)) | |
250 | + return ERROR_IE_TABLE_NOT_FOUND; | |
251 | + ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; | |
252 | + if (ie_info->num_keys == 0 || ie_info->num_keys > 32) | |
253 | + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; | |
254 | + | |
255 | + ie_num = hdr->ie_key_sel; | |
256 | + if (ie_num == 0 || ie_num > ie_info->num_keys) | |
257 | + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; | |
258 | + | |
259 | + ie_revoc_flag = ie_info->key_revok; | |
260 | + if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) | |
261 | + return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; | |
262 | + | |
263 | + ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; | |
264 | + | |
265 | + if (!CHECK_KEY_LEN(ie_key_len)) | |
266 | + return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; | |
267 | + | |
268 | + memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), | |
269 | + ie_key_len); | |
270 | + | |
271 | + img->key_len = ie_key_len; | |
272 | + return 0; | |
273 | +} | |
274 | +#endif | |
275 | + | |
276 | + | |
277 | +/* This function return length of public key.*/ | |
278 | +static inline u32 get_key_len(struct fsl_secboot_img_priv *img) | |
279 | +{ | |
280 | + return img->key_len; | |
281 | +} | |
282 | + | |
283 | +/* | |
284 | + * Handles the ESBC uboot client header verification failure. | |
285 | + * This function handles all the errors which might occur in the | |
286 | + * parsing and checking of ESBC uboot client header. It will also | |
287 | + * set the error bits in the SEC_MON. | |
288 | + */ | |
289 | +static void fsl_secboot_header_verification_failure(void) | |
290 | +{ | |
291 | + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) | |
292 | + (CONFIG_SYS_SEC_MON_ADDR); | |
293 | + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); | |
294 | + u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); | |
295 | + | |
296 | + /* 29th bit of OSPR is ITS */ | |
297 | + u32 its = sfp_in32(&sfp_regs->ospr) >> 2; | |
298 | + | |
299 | + /* | |
300 | + * Read the SEC_MON status register | |
301 | + * Read SSM_ST field | |
302 | + */ | |
303 | + sts = sec_mon_in32(&sec_mon_regs->hp_stat); | |
304 | + if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { | |
305 | + if (its == 1) | |
306 | + change_sec_mon_state(HPSR_SSM_ST_TRUST, | |
307 | + HPSR_SSM_ST_SOFT_FAIL); | |
308 | + else | |
309 | + change_sec_mon_state(HPSR_SSM_ST_TRUST, | |
310 | + HPSR_SSM_ST_NON_SECURE); | |
311 | + } | |
312 | + | |
313 | + printf("Generating reset request\n"); | |
314 | + do_reset(NULL, 0, 0, NULL); | |
315 | +} | |
316 | + | |
317 | +/* | |
318 | + * Handles the ESBC uboot client image verification failure. | |
319 | + * This function handles all the errors which might occur in the | |
320 | + * public key hash comparison and signature verification of | |
321 | + * ESBC uboot client image. It will also | |
322 | + * set the error bits in the SEC_MON. | |
323 | + */ | |
324 | +static void fsl_secboot_image_verification_failure(void) | |
325 | +{ | |
326 | + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) | |
327 | + (CONFIG_SYS_SEC_MON_ADDR); | |
328 | + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); | |
329 | + u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); | |
330 | + | |
331 | + u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT; | |
332 | + | |
333 | + /* | |
334 | + * Read the SEC_MON status register | |
335 | + * Read SSM_ST field | |
336 | + */ | |
337 | + sts = sec_mon_in32(&sec_mon_regs->hp_stat); | |
338 | + if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { | |
339 | + if (its == 1) { | |
340 | + change_sec_mon_state(HPSR_SSM_ST_TRUST, | |
341 | + HPSR_SSM_ST_SOFT_FAIL); | |
342 | + | |
343 | + printf("Generating reset request\n"); | |
344 | + do_reset(NULL, 0, 0, NULL); | |
345 | + } else { | |
346 | + change_sec_mon_state(HPSR_SSM_ST_TRUST, | |
347 | + HPSR_SSM_ST_NON_SECURE); | |
348 | + } | |
349 | + } | |
350 | +} | |
351 | + | |
352 | +static void fsl_secboot_bootscript_parse_failure(void) | |
353 | +{ | |
354 | + fsl_secboot_header_verification_failure(); | |
355 | +} | |
356 | + | |
357 | +/* | |
358 | + * Handles the errors in esbc boot. | |
359 | + * This function handles all the errors which might occur in the | |
360 | + * esbc boot phase. It will call the appropriate api to log the | |
361 | + * errors and set the error bits in the SEC_MON. | |
362 | + */ | |
363 | +void fsl_secboot_handle_error(int error) | |
364 | +{ | |
365 | + const struct fsl_secboot_errcode *e; | |
366 | + | |
367 | + for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX; | |
368 | + e++) { | |
369 | + if (e->errcode == error) | |
370 | + printf("ERROR :: %x :: %s\n", error, e->name); | |
371 | + } | |
372 | + | |
373 | + /* If Boot Mode is secure, transition the SNVS state and issue | |
374 | + * reset based on type of failure and ITS setting. | |
375 | + * If Boot mode is non-secure, return from this function. | |
376 | + */ | |
377 | + if (fsl_check_boot_mode_secure() == 0) | |
378 | + return; | |
379 | + | |
380 | + switch (error) { | |
381 | + case ERROR_ESBC_CLIENT_HEADER_BARKER: | |
382 | + case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: | |
383 | + case ERROR_ESBC_CLIENT_HEADER_KEY_LEN: | |
384 | + case ERROR_ESBC_CLIENT_HEADER_SIG_LEN: | |
385 | + case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN: | |
386 | + case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1: | |
387 | + case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2: | |
388 | + case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD: | |
389 | + case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP: | |
390 | + case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD: | |
391 | +#ifdef CONFIG_KEY_REVOCATION | |
392 | + case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED: | |
393 | + case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY: | |
394 | + case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM: | |
395 | + case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN: | |
396 | +#endif | |
397 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
398 | + /*@fallthrough@*/ | |
399 | + case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED: | |
400 | + case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY: | |
401 | + case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM: | |
402 | + case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN: | |
403 | + case ERROR_IE_TABLE_NOT_FOUND: | |
404 | +#endif | |
405 | + fsl_secboot_header_verification_failure(); | |
406 | + break; | |
407 | + case ERROR_ESBC_SEC_RESET: | |
408 | + case ERROR_ESBC_SEC_DEQ: | |
409 | + case ERROR_ESBC_SEC_ENQ: | |
410 | + case ERROR_ESBC_SEC_DEQ_TO: | |
411 | + case ERROR_ESBC_SEC_JOBQ_STATUS: | |
412 | + case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY: | |
413 | + case ERROR_ESBC_CLIENT_HASH_COMPARE_EM: | |
414 | + fsl_secboot_image_verification_failure(); | |
415 | + break; | |
416 | + case ERROR_ESBC_MISSING_BOOTM: | |
417 | + fsl_secboot_bootscript_parse_failure(); | |
418 | + break; | |
419 | + case ERROR_ESBC_WRONG_CMD: | |
420 | + default: | |
421 | + branch_to_self(); | |
422 | + break; | |
423 | + } | |
424 | +} | |
425 | + | |
426 | +static void fsl_secblk_handle_error(int error) | |
427 | +{ | |
428 | + switch (error) { | |
429 | + case ERROR_ESBC_SEC_ENQ: | |
430 | + fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ); | |
431 | + break; | |
432 | + case ERROR_ESBC_SEC_DEQ: | |
433 | + fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ); | |
434 | + break; | |
435 | + case ERROR_ESBC_SEC_DEQ_TO: | |
436 | + fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO); | |
437 | + break; | |
438 | + default: | |
439 | + printf("Job Queue Output status %x\n", error); | |
440 | + fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS); | |
441 | + break; | |
442 | + } | |
443 | +} | |
444 | + | |
445 | +/* | |
446 | + * Calculate hash of key obtained via offset present in ESBC uboot | |
447 | + * client hdr. This function calculates the hash of key which is obtained | |
448 | + * through offset present in ESBC uboot client header. | |
449 | + */ | |
450 | +static int calc_img_key_hash(struct fsl_secboot_img_priv *img) | |
451 | +{ | |
452 | + struct hash_algo *algo; | |
453 | + void *ctx; | |
454 | + int i, srk = 0; | |
455 | + int ret = 0; | |
456 | + const char *algo_name = "sha256"; | |
457 | + | |
458 | + /* Calculate hash of the esbc key */ | |
459 | + ret = hash_progressive_lookup_algo(algo_name, &algo); | |
460 | + if (ret) | |
461 | + return ret; | |
462 | + | |
463 | + ret = algo->hash_init(algo, &ctx); | |
464 | + if (ret) | |
465 | + return ret; | |
466 | + | |
467 | + /* Update hash for ESBC key */ | |
468 | +#ifdef CONFIG_KEY_REVOCATION | |
469 | + if (check_srk(img)) { | |
470 | + ret = algo->hash_update(algo, ctx, | |
471 | + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), | |
472 | + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); | |
473 | + srk = 1; | |
474 | + } | |
475 | +#endif | |
476 | + if (!srk) | |
477 | + ret = algo->hash_update(algo, ctx, | |
478 | + img->img_key, img->key_len, 1); | |
479 | + if (ret) | |
480 | + return ret; | |
481 | + | |
482 | + /* Copy hash at destination buffer */ | |
483 | + ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); | |
484 | + if (ret) | |
485 | + return ret; | |
486 | + | |
487 | + for (i = 0; i < SHA256_BYTES; i++) | |
488 | + img->img_key_hash[i] = hash_val[i]; | |
489 | + | |
490 | + return 0; | |
491 | +} | |
492 | + | |
493 | +/* | |
494 | + * Calculate hash of ESBC hdr and ESBC. This function calculates the | |
495 | + * single hash of ESBC header and ESBC image. If SG flag is on, all | |
496 | + * SG entries are also hashed alongwith the complete SG table. | |
497 | + */ | |
498 | +static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) | |
499 | +{ | |
500 | + struct hash_algo *algo; | |
501 | + void *ctx; | |
502 | + int ret = 0; | |
503 | + int key_hash = 0; | |
504 | + const char *algo_name = "sha256"; | |
505 | + | |
506 | + /* Calculate the hash of the ESBC */ | |
507 | + ret = hash_progressive_lookup_algo(algo_name, &algo); | |
508 | + if (ret) | |
509 | + return ret; | |
510 | + | |
511 | + ret = algo->hash_init(algo, &ctx); | |
512 | + /* Copy hash at destination buffer */ | |
513 | + if (ret) | |
514 | + return ret; | |
515 | + | |
516 | + /* Update hash for CSF Header */ | |
517 | + ret = algo->hash_update(algo, ctx, | |
518 | + (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0); | |
519 | + if (ret) | |
520 | + return ret; | |
521 | + | |
522 | + /* Update the hash with that of srk table if srk flag is 1 | |
523 | + * If IE Table is selected, key is not added in the hash | |
524 | + * If neither srk table nor IE key table available, add key | |
525 | + * from header in the hash calculation | |
526 | + */ | |
527 | +#ifdef CONFIG_KEY_REVOCATION | |
528 | + if (check_srk(img)) { | |
529 | + ret = algo->hash_update(algo, ctx, | |
530 | + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), | |
531 | + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); | |
532 | + key_hash = 1; | |
533 | + } | |
534 | +#endif | |
535 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
536 | + if (!key_hash && check_ie(img)) | |
537 | + key_hash = 1; | |
538 | +#endif | |
539 | + if (!key_hash) | |
540 | + ret = algo->hash_update(algo, ctx, | |
541 | + img->img_key, img->hdr.key_len, 0); | |
542 | + if (ret) | |
543 | + return ret; | |
544 | + | |
545 | + /* Update hash for actual Image */ | |
546 | + ret = algo->hash_update(algo, ctx, | |
547 | + (u8 *)img->img_addr, img->img_size, 1); | |
548 | + if (ret) | |
549 | + return ret; | |
550 | + | |
551 | + /* Copy hash at destination buffer */ | |
552 | + ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); | |
553 | + if (ret) | |
554 | + return ret; | |
555 | + | |
556 | + return 0; | |
557 | +} | |
558 | + | |
559 | +/* | |
560 | + * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the | |
561 | + * pointers for padding, DER value and hash. And finally, constructs EM' | |
562 | + * which includes hash of complete CSF header and ESBC image. If SG flag | |
563 | + * is on, hash of SG table and entries is also included. | |
564 | + */ | |
565 | +static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img) | |
566 | +{ | |
567 | + /* | |
568 | + * RSA PKCSv1.5 encoding format for encoded message is below | |
569 | + * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash | |
570 | + * PS is Padding String | |
571 | + * DER is DER value for SHA-256 | |
572 | + * Hash is SHA-256 hash | |
573 | + * ********************************************************* | |
574 | + * representative points to first byte of EM initially and is | |
575 | + * filled with 0x0 | |
576 | + * representative is incremented by 1 and second byte is filled | |
577 | + * with 0x1 | |
578 | + * padding points to third byte of EM | |
579 | + * digest points to full length of EM - 32 bytes | |
580 | + * hash_id (DER value) points to 19 bytes before pDigest | |
581 | + * separator is one byte which separates padding and DER | |
582 | + */ | |
583 | + | |
584 | + size_t len; | |
585 | + u8 *representative; | |
586 | + u8 *padding, *digest; | |
587 | + u8 *hash_id, *separator; | |
588 | + int i; | |
589 | + | |
590 | + len = (get_key_len(img) / 2) - 1; | |
591 | + representative = img->img_encoded_hash_second; | |
592 | + representative[0] = 0; | |
593 | + representative[1] = 1; /* block type 1 */ | |
594 | + | |
595 | + padding = &representative[2]; | |
596 | + digest = &representative[1] + len - 32; | |
597 | + hash_id = digest - sizeof(hash_identifier); | |
598 | + separator = hash_id - 1; | |
599 | + | |
600 | + /* fill padding area pointed by padding with 0xff */ | |
601 | + memset(padding, 0xff, separator - padding); | |
602 | + | |
603 | + /* fill byte pointed by separator */ | |
604 | + *separator = 0; | |
605 | + | |
606 | + /* fill SHA-256 DER value pointed by HashId */ | |
607 | + memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); | |
608 | + | |
609 | + /* fill hash pointed by Digest */ | |
610 | + for (i = 0; i < SHA256_BYTES; i++) | |
611 | + digest[i] = hash_val[i]; | |
612 | +} | |
613 | + | |
614 | +/* | |
615 | + * Reads and validates the ESBC client header. | |
616 | + * This function reads key and signature from the ESBC client header. | |
617 | + * If Scatter/Gather flag is on, lengths and offsets of images | |
618 | + * present as SG entries are also read. This function also checks | |
619 | + * whether the header is valid or not. | |
620 | + */ | |
621 | +static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) | |
622 | +{ | |
623 | + char buf[20]; | |
624 | + struct fsl_secboot_img_hdr *hdr = &img->hdr; | |
625 | + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; | |
626 | + u8 *k, *s; | |
627 | + u32 ret = 0; | |
628 | + | |
629 | +#ifdef CONFIG_KEY_REVOCATION | |
630 | +#endif | |
631 | + int key_found = 0; | |
632 | + | |
633 | + /* check barker code */ | |
634 | + if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) | |
635 | + return ERROR_ESBC_CLIENT_HEADER_BARKER; | |
636 | + | |
637 | + /* If Image Address is not passed as argument to function, | |
638 | + * then Address and Size must be read from the Header. | |
639 | + */ | |
640 | + if (img->img_addr == 0) { | |
641 | + #ifdef CONFIG_ESBC_ADDR_64BIT | |
642 | + img->img_addr = hdr->pimg64; | |
643 | + #else | |
644 | + img->img_addr = hdr->pimg; | |
645 | + #endif | |
646 | + } | |
647 | + | |
648 | + sprintf(buf, "%lx", img->img_addr); | |
649 | + setenv("img_addr", buf); | |
650 | + | |
651 | + if (!hdr->img_size) | |
652 | + return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; | |
653 | + | |
654 | + img->img_size = hdr->img_size; | |
655 | + | |
656 | + /* Key checking*/ | |
657 | +#ifdef CONFIG_KEY_REVOCATION | |
658 | + if (check_srk(img)) { | |
659 | + ret = read_validate_srk_tbl(img); | |
660 | + if (ret != 0) | |
661 | + return ret; | |
662 | + key_found = 1; | |
663 | + } | |
664 | +#endif | |
665 | + | |
666 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
667 | + if (!key_found && check_ie(img)) { | |
668 | + ret = read_validate_ie_tbl(img); | |
669 | + if (ret != 0) | |
670 | + return ret; | |
671 | + key_found = 1; | |
672 | + } | |
673 | +#endif | |
674 | + | |
675 | + if (key_found == 0) { | |
676 | + ret = read_validate_single_key(img); | |
677 | + if (ret != 0) | |
678 | + return ret; | |
679 | + key_found = 1; | |
680 | + } | |
681 | + | |
682 | + /* check signaure */ | |
683 | + if (get_key_len(img) == 2 * hdr->sign_len) { | |
684 | + /* check signature length */ | |
685 | + if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) || | |
686 | + (hdr->sign_len == KEY_SIZE_BYTES / 2) || | |
687 | + (hdr->sign_len == KEY_SIZE_BYTES))) | |
688 | + return ERROR_ESBC_CLIENT_HEADER_SIG_LEN; | |
689 | + } else { | |
690 | + return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN; | |
691 | + } | |
692 | + | |
693 | + memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len); | |
694 | + | |
695 | + /* No SG support */ | |
696 | + if (hdr->sg_flag) | |
697 | + return ERROR_ESBC_CLIENT_HEADER_SG; | |
698 | + | |
699 | + /* modulus most significant bit should be set */ | |
700 | + k = (u8 *)&img->img_key; | |
701 | + | |
702 | + if ((k[0] & 0x80) == 0) | |
703 | + return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1; | |
704 | + | |
705 | + /* modulus value should be odd */ | |
706 | + if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0) | |
707 | + return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2; | |
708 | + | |
709 | + /* Check signature value < modulus value */ | |
710 | + s = (u8 *)&img->img_sign; | |
711 | + | |
712 | + if (!(memcmp(s, k, hdr->sign_len) < 0)) | |
713 | + return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD; | |
714 | + | |
715 | + return ESBC_VALID_HDR; | |
716 | +} | |
717 | + | |
718 | +static inline int str2longbe(const char *p, ulong *num) | |
719 | +{ | |
720 | + char *endptr; | |
721 | + ulong tmp; | |
722 | + | |
723 | + if (!p) { | |
724 | + return 0; | |
725 | + } else { | |
726 | + tmp = simple_strtoul(p, &endptr, 16); | |
727 | + if (sizeof(ulong) == 4) | |
728 | + *num = cpu_to_be32(tmp); | |
729 | + else | |
730 | + *num = cpu_to_be64(tmp); | |
731 | + } | |
732 | + | |
733 | + return *p != '\0' && *endptr == '\0'; | |
734 | +} | |
735 | +/* Function to calculate the ESBC Image Hash | |
736 | + * and hash from Digital signature. | |
737 | + * The Two hash's are compared to yield the | |
738 | + * result of signature validation. | |
739 | + */ | |
740 | +static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) | |
741 | +{ | |
742 | + int ret; | |
743 | + uint32_t key_len; | |
744 | + struct key_prop prop; | |
745 | +#if !defined(USE_HOSTCC) | |
746 | + struct udevice *mod_exp_dev; | |
747 | +#endif | |
748 | + ret = calc_esbchdr_esbc_hash(img); | |
749 | + if (ret) | |
750 | + return ret; | |
751 | + | |
752 | + /* Construct encoded hash EM' wrt PKCSv1.5 */ | |
753 | + construct_img_encoded_hash_second(img); | |
754 | + | |
755 | + /* Fill prop structure for public key */ | |
756 | + memset(&prop, 0, sizeof(struct key_prop)); | |
757 | + key_len = get_key_len(img) / 2; | |
758 | + prop.modulus = img->img_key; | |
759 | + prop.public_exponent = img->img_key + key_len; | |
760 | + prop.num_bits = key_len * 8; | |
761 | + prop.exp_len = key_len; | |
762 | + | |
763 | + ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); | |
764 | + if (ret) { | |
765 | + printf("RSA: Can't find Modular Exp implementation\n"); | |
766 | + return -EINVAL; | |
767 | + } | |
768 | + | |
769 | + ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, | |
770 | + &prop, img->img_encoded_hash); | |
771 | + if (ret) | |
772 | + return ret; | |
773 | + | |
774 | + /* | |
775 | + * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 | |
776 | + * memcmp returns zero on success | |
777 | + * memcmp returns non-zero on failure | |
778 | + */ | |
779 | + ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, | |
780 | + img->hdr.sign_len); | |
781 | + | |
782 | + if (ret) | |
783 | + return ERROR_ESBC_CLIENT_HASH_COMPARE_EM; | |
784 | + | |
785 | + return 0; | |
786 | +} | |
787 | + | |
788 | +int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str, | |
789 | + uintptr_t img_addr) | |
790 | +{ | |
791 | + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); | |
792 | + ulong hash[SHA256_BYTES/sizeof(ulong)]; | |
793 | + char hash_str[NUM_HEX_CHARS + 1]; | |
794 | + struct fsl_secboot_img_priv *img; | |
795 | + struct fsl_secboot_img_hdr *hdr; | |
796 | + void *esbc; | |
797 | + int ret, i, hash_cmd = 0; | |
798 | + u32 srk_hash[8]; | |
799 | + | |
800 | + if (arg_hash_str != NULL) { | |
801 | + const char *cp = arg_hash_str; | |
802 | + int i = 0; | |
803 | + | |
804 | + if (*cp == '0' && *(cp + 1) == 'x') | |
805 | + cp += 2; | |
806 | + | |
807 | + /* The input string expected is in hex, where | |
808 | + * each 4 bits would be represented by a hex | |
809 | + * sha256 hash is 256 bits long, which would mean | |
810 | + * num of characters = 256 / 4 | |
811 | + */ | |
812 | + if (strlen(cp) != SHA256_NIBBLES) { | |
813 | + printf("%s is not a 256 bits hex string as expected\n", | |
814 | + arg_hash_str); | |
815 | + return -1; | |
816 | + } | |
817 | + | |
818 | + for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) { | |
819 | + strncpy(hash_str, cp + (i * NUM_HEX_CHARS), | |
820 | + NUM_HEX_CHARS); | |
821 | + hash_str[NUM_HEX_CHARS] = '\0'; | |
822 | + if (!str2longbe(hash_str, &hash[i])) { | |
823 | + printf("%s is not a 256 bits hex string ", | |
824 | + arg_hash_str); | |
825 | + return -1; | |
826 | + } | |
827 | + } | |
828 | + | |
829 | + hash_cmd = 1; | |
830 | + } | |
831 | + | |
832 | + img = malloc(sizeof(struct fsl_secboot_img_priv)); | |
833 | + | |
834 | + if (!img) | |
835 | + return -1; | |
836 | + | |
837 | + memset(img, 0, sizeof(struct fsl_secboot_img_priv)); | |
838 | + | |
839 | + /* Update the information in Private Struct */ | |
840 | + hdr = &img->hdr; | |
841 | + img->ehdrloc = haddr; | |
842 | + img->img_addr = img_addr; | |
843 | + esbc = (u8 *)img->ehdrloc; | |
844 | + | |
845 | + memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); | |
846 | + | |
847 | + /* read and validate esbc header */ | |
848 | + ret = read_validate_esbc_client_header(img); | |
849 | + | |
850 | + if (ret != ESBC_VALID_HDR) { | |
851 | + fsl_secboot_handle_error(ret); | |
852 | + goto exit; | |
853 | + } | |
854 | + | |
855 | + /* SRKH present in SFP */ | |
856 | + for (i = 0; i < NUM_SRKH_REGS; i++) | |
857 | + srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]); | |
858 | + | |
859 | + /* | |
860 | + * Calculate hash of key obtained via offset present in | |
861 | + * ESBC uboot client hdr | |
862 | + */ | |
863 | + ret = calc_img_key_hash(img); | |
864 | + if (ret) { | |
865 | + fsl_secblk_handle_error(ret); | |
866 | + goto exit; | |
867 | + } | |
868 | + | |
869 | + /* Compare hash obtained above with SRK hash present in SFP */ | |
870 | + if (hash_cmd) | |
871 | + ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES); | |
872 | + else | |
873 | + ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES); | |
874 | + | |
875 | +#if defined(CONFIG_FSL_ISBC_KEY_EXT) | |
876 | + if (!hash_cmd && check_ie(img)) | |
877 | + ret = 0; | |
878 | +#endif | |
879 | + | |
880 | + if (ret != 0) { | |
881 | + fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY); | |
882 | + goto exit; | |
883 | + } | |
884 | + | |
885 | + ret = calculate_cmp_img_sig(img); | |
886 | + if (ret) { | |
887 | + fsl_secboot_handle_error(ret); | |
888 | + goto exit; | |
889 | + } | |
890 | + | |
891 | +exit: | |
892 | + return ret; | |
893 | +} |
board/embedian/common/mmc.c
1 | +/* | |
2 | + * Copyright (C) 2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | +#include <common.h> | |
7 | +#include <asm/arch/sys_proto.h> | |
8 | +#include <asm/errno.h> | |
9 | +#include <asm/io.h> | |
10 | +#include <stdbool.h> | |
11 | + | |
12 | +static int check_mmc_autodetect(void) | |
13 | +{ | |
14 | + char *autodetect_str = getenv("mmcautodetect"); | |
15 | + | |
16 | + if ((autodetect_str != NULL) && | |
17 | + (strcmp(autodetect_str, "yes") == 0)) { | |
18 | + return 1; | |
19 | + } | |
20 | + | |
21 | + return 0; | |
22 | +} | |
23 | + | |
24 | +/* This should be defined for each board */ | |
25 | +__weak int mmc_map_to_kernel_blk(int dev_no) | |
26 | +{ | |
27 | + return dev_no; | |
28 | +} | |
29 | + | |
30 | +void board_late_mmc_env_init(void) | |
31 | +{ | |
32 | + char cmd[32]; | |
33 | + char mmcblk[32]; | |
34 | + u32 dev_no = mmc_get_env_dev(); | |
35 | + | |
36 | + if (!check_mmc_autodetect()) | |
37 | + return; | |
38 | + | |
39 | + setenv_ulong("mmcdev", dev_no); | |
40 | + | |
41 | + /* Set mmcblk env */ | |
42 | + sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", | |
43 | + mmc_map_to_kernel_blk(dev_no)); | |
44 | + setenv("mmcroot", mmcblk); | |
45 | + | |
46 | + sprintf(cmd, "mmc dev %d", dev_no); | |
47 | + run_command(cmd, 0); | |
48 | +} |
board/embedian/common/recovery.c
1 | +/* | |
2 | + * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | +#include <common.h> | |
7 | +#include <malloc.h> | |
8 | +#include <recovery.h> | |
9 | +#ifdef CONFIG_MXC_KPD | |
10 | +#include <mxc_keyb.h> | |
11 | +#endif | |
12 | +#include <asm/imx-common/boot_mode.h> | |
13 | + | |
14 | +#ifdef CONFIG_MXC_KPD | |
15 | +#define PRESSED_VOL_DOWN 0x01 | |
16 | +#define PRESSED_POWER 0x02 | |
17 | +#define RECOVERY_KEY_MASK (PRESSED_VOL_DOWN | PRESSED_POWER) | |
18 | + | |
19 | +inline int test_key(int value, struct kpp_key_info *ki) | |
20 | +{ | |
21 | + return (ki->val == value) && (ki->evt == KDepress); | |
22 | +} | |
23 | + | |
24 | +int check_key_pressing(void) | |
25 | +{ | |
26 | + struct kpp_key_info *key_info = NULL; | |
27 | + int state = 0, keys, i; | |
28 | + | |
29 | + int ret = 0; | |
30 | + | |
31 | + mxc_kpp_init(); | |
32 | + /* due to glitch suppression circuit, | |
33 | + wait sometime to let all keys scanned. */ | |
34 | + udelay(1000); | |
35 | + keys = mxc_kpp_getc(&key_info); | |
36 | + | |
37 | + printf("Detecting VOL_DOWN+POWER key for recovery(%d:%d) ...\n", | |
38 | + keys, keys ? key_info->val : 0); | |
39 | + if (keys > 1) { | |
40 | + for (i = 0; i < keys; i++) { | |
41 | + if (test_key(CONFIG_POWER_KEY, &key_info[i])) | |
42 | + state |= PRESSED_POWER; | |
43 | + else if (test_key(CONFIG_VOL_DOWN_KEY, &key_info[i])) | |
44 | + state |= PRESSED_VOL_DOWN; | |
45 | + } | |
46 | + } | |
47 | + if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK) | |
48 | + ret = 1; | |
49 | + if (key_info) | |
50 | + free(key_info); | |
51 | + return ret; | |
52 | +} | |
53 | +#else | |
54 | +/* If not using mxc keypad, currently we will detect power key on board */ | |
55 | +int check_key_pressing(void) | |
56 | +{ | |
57 | + return 0; | |
58 | +} | |
59 | +#endif | |
60 | + | |
61 | +void setup_recovery_env(void) | |
62 | +{ | |
63 | + board_recovery_setup(); | |
64 | +} | |
65 | + | |
66 | +/* export to lib_arm/board.c */ | |
67 | +void check_recovery_mode(void) | |
68 | +{ | |
69 | + if (check_key_pressing()) { | |
70 | + puts("Fastboot: Recovery key pressing got!\n"); | |
71 | + setup_recovery_env(); | |
72 | + } else if (check_recovery_cmd_file()) { | |
73 | + puts("Fastboot: Recovery command file found!\n"); | |
74 | + setup_recovery_env(); | |
75 | + } else { | |
76 | + puts("Fastboot: Normal\n"); | |
77 | + } | |
78 | +} |
board/embedian/common/sdhc_boot.c
1 | +/* | |
2 | + * Copyright 2011 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <mmc.h> | |
9 | +#include <malloc.h> | |
10 | + | |
11 | +/* | |
12 | + * The environment variables are written to just after the u-boot image | |
13 | + * on SDCard, so we must read the MBR to get the start address and code | |
14 | + * length of the u-boot image, then calculate the address of the env. | |
15 | + */ | |
16 | +#define ESDHC_BOOT_IMAGE_SIZE 0x48 | |
17 | +#define ESDHC_BOOT_IMAGE_ADDR 0x50 | |
18 | + | |
19 | +#define ESDHC_DEFAULT_ENVADDR 0x400 | |
20 | + | |
21 | +int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) | |
22 | +{ | |
23 | + u8 *tmp_buf; | |
24 | + u32 blklen, code_offset, code_len, n; | |
25 | + | |
26 | + blklen = mmc->read_bl_len; | |
27 | + tmp_buf = malloc(blklen); | |
28 | + if (!tmp_buf) | |
29 | + return 1; | |
30 | + | |
31 | + /* read out the first block, get the config data information */ | |
32 | + n = mmc->block_dev.block_read(&mmc->block_dev, 0, 1, tmp_buf); | |
33 | + if (!n) { | |
34 | + free(tmp_buf); | |
35 | + return 1; | |
36 | + } | |
37 | + | |
38 | + /* Get the Source Address, from offset 0x50 */ | |
39 | + code_offset = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_ADDR); | |
40 | + | |
41 | + /* Get the code size from offset 0x48 */ | |
42 | + code_len = *(u32 *)(tmp_buf + ESDHC_BOOT_IMAGE_SIZE); | |
43 | + | |
44 | +#ifdef CONFIG_ESDHC_HC_BLK_ADDR | |
45 | + /* | |
46 | + * On soc BSC9131, BSC9132: | |
47 | + * In High Capacity SD Cards (> 2 GBytes), the 32-bit source address and | |
48 | + * code length of these soc specify the memory address in block address | |
49 | + * format. Block length is fixed to 512 bytes as per the SD High | |
50 | + * Capacity specification. | |
51 | + */ | |
52 | + u64 tmp; | |
53 | + | |
54 | + if (mmc->high_capacity) { | |
55 | + tmp = (u64)code_offset * blklen; | |
56 | + tmp += code_len * blklen; | |
57 | + } else | |
58 | + tmp = code_offset + code_len; | |
59 | + | |
60 | + if ((tmp + CONFIG_ENV_SIZE > mmc->capacity) || | |
61 | + (tmp > 0xFFFFFFFFU)) | |
62 | + *env_addr = ESDHC_DEFAULT_ENVADDR; | |
63 | + else | |
64 | + *env_addr = tmp; | |
65 | + | |
66 | + free(tmp_buf); | |
67 | + | |
68 | + return 0; | |
69 | +#endif | |
70 | + | |
71 | + *env_addr = code_offset + code_len; | |
72 | + | |
73 | + free(tmp_buf); | |
74 | + | |
75 | + return 0; | |
76 | +} |
board/embedian/common/sleep.h
1 | +/* | |
2 | + * Copyright 2014 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#ifndef __SLEEP_H | |
8 | +#define __SLEEP_H | |
9 | + | |
10 | +#define DCFG_CCSR_CRSTSR_WDRFR (1 << 3) | |
11 | +#define DDR_BUFF_LEN 128 | |
12 | + | |
13 | +/* determine if it is a wakeup from deep sleep */ | |
14 | +bool is_warm_boot(void); | |
15 | + | |
16 | +/* disable console output */ | |
17 | +void fsl_dp_disable_console(void); | |
18 | + | |
19 | +/* clean up everything and jump to kernel */ | |
20 | +int fsl_dp_resume(void); | |
21 | +#endif |
board/embedian/common/sys_eeprom.c
1 | +/* | |
2 | + * Copyright 2006, 2008-2009, 2011 Freescale Semiconductor | |
3 | + * York Sun (yorksun@freescale.com) | |
4 | + * Haiying Wang (haiying.wang@freescale.com) | |
5 | + * Timur Tabi (timur@freescale.com) | |
6 | + * | |
7 | + * SPDX-License-Identifier: GPL-2.0+ | |
8 | + */ | |
9 | + | |
10 | +#include <common.h> | |
11 | +#include <command.h> | |
12 | +#include <i2c.h> | |
13 | +#include <linux/ctype.h> | |
14 | + | |
15 | +#ifdef CONFIG_SYS_I2C_EEPROM_CCID | |
16 | +#include "../common/eeprom.h" | |
17 | +#define MAX_NUM_PORTS 8 | |
18 | +#endif | |
19 | + | |
20 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
21 | +/* some boards with non-256-bytes EEPROM have special define */ | |
22 | +/* for MAX_NUM_PORTS in board-specific file */ | |
23 | +#ifndef MAX_NUM_PORTS | |
24 | +#define MAX_NUM_PORTS 16 | |
25 | +#endif | |
26 | +#define NXID_VERSION 1 | |
27 | +#endif | |
28 | + | |
29 | +/** | |
30 | + * static eeprom: EEPROM layout for CCID or NXID formats | |
31 | + * | |
32 | + * See application note AN3638 for details. | |
33 | + */ | |
34 | +static struct __attribute__ ((__packed__)) eeprom { | |
35 | +#ifdef CONFIG_SYS_I2C_EEPROM_CCID | |
36 | + u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'CCID' */ | |
37 | + u8 major; /* 0x04 Board revision, major */ | |
38 | + u8 minor; /* 0x05 Board revision, minor */ | |
39 | + u8 sn[10]; /* 0x06 - 0x0F Serial Number*/ | |
40 | + u8 errata[2]; /* 0x10 - 0x11 Errata Level */ | |
41 | + u8 date[6]; /* 0x12 - 0x17 Build Date */ | |
42 | + u8 res_0[40]; /* 0x18 - 0x3f Reserved */ | |
43 | + u8 mac_count; /* 0x40 Number of MAC addresses */ | |
44 | + u8 mac_flag; /* 0x41 MAC table flags */ | |
45 | + u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0x71 MAC addresses */ | |
46 | + u32 crc; /* 0x72 CRC32 checksum */ | |
47 | +#endif | |
48 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
49 | + u8 id[4]; /* 0x00 - 0x03 EEPROM Tag 'NXID' */ | |
50 | + u8 sn[12]; /* 0x04 - 0x0F Serial Number */ | |
51 | + u8 errata[5]; /* 0x10 - 0x14 Errata Level */ | |
52 | + u8 date[6]; /* 0x15 - 0x1a Build Date */ | |
53 | + u8 res_0; /* 0x1b Reserved */ | |
54 | + u32 version; /* 0x1c - 0x1f NXID Version */ | |
55 | + u8 tempcal[8]; /* 0x20 - 0x27 Temperature Calibration Factors */ | |
56 | + u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */ | |
57 | + u8 tempcalflags; /* 0x2a Temperature Calibration Flags */ | |
58 | + u8 res_1[21]; /* 0x2b - 0x3f Reserved */ | |
59 | + u8 mac_count; /* 0x40 Number of MAC addresses */ | |
60 | + u8 mac_flag; /* 0x41 MAC table flags */ | |
61 | + u8 mac[MAX_NUM_PORTS][6]; /* 0x42 - 0xa1 MAC addresses */ | |
62 | + u8 res_2[90]; /* 0xa2 - 0xfb Reserved */ | |
63 | + u32 crc; /* 0xfc - 0xff CRC32 checksum */ | |
64 | +#endif | |
65 | +} e; | |
66 | + | |
67 | +/* Set to 1 if we've read EEPROM into memory */ | |
68 | +static int has_been_read = 0; | |
69 | + | |
70 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
71 | +/* Is this a valid NXID EEPROM? */ | |
72 | +#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \ | |
73 | + (e.id[2] == 'I') || (e.id[3] == 'D')) | |
74 | +#endif | |
75 | + | |
76 | +#ifdef CONFIG_SYS_I2C_EEPROM_CCID | |
77 | +/* Is this a valid CCID EEPROM? */ | |
78 | +#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \ | |
79 | + (e.id[2] == 'I') || (e.id[3] == 'D')) | |
80 | +#endif | |
81 | + | |
82 | +/** | |
83 | + * show_eeprom - display the contents of the EEPROM | |
84 | + */ | |
85 | +static void show_eeprom(void) | |
86 | +{ | |
87 | + int i; | |
88 | + unsigned int crc; | |
89 | + | |
90 | + /* EEPROM tag ID, either CCID or NXID */ | |
91 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
92 | + printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], | |
93 | + be32_to_cpu(e.version)); | |
94 | +#else | |
95 | + printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); | |
96 | +#endif | |
97 | + | |
98 | + /* Serial number */ | |
99 | + printf("SN: %s\n", e.sn); | |
100 | + | |
101 | + /* Errata level. */ | |
102 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
103 | + printf("Errata: %s\n", e.errata); | |
104 | +#else | |
105 | + printf("Errata: %c%c\n", | |
106 | + e.errata[0] ? e.errata[0] : '.', | |
107 | + e.errata[1] ? e.errata[1] : '.'); | |
108 | +#endif | |
109 | + | |
110 | + /* Build date, BCD date values, as YYMMDDhhmmss */ | |
111 | + printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n", | |
112 | + e.date[0], e.date[1], e.date[2], | |
113 | + e.date[3] & 0x7F, e.date[4], e.date[5], | |
114 | + e.date[3] & 0x80 ? "PM" : ""); | |
115 | + | |
116 | + /* Show MAC addresses */ | |
117 | + for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) { | |
118 | + | |
119 | + u8 *p = e.mac[i]; | |
120 | + | |
121 | + printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i, | |
122 | + p[0], p[1], p[2], p[3], p[4], p[5]); | |
123 | + } | |
124 | + | |
125 | + crc = crc32(0, (void *)&e, sizeof(e) - 4); | |
126 | + | |
127 | + if (crc == be32_to_cpu(e.crc)) | |
128 | + printf("CRC: %08x\n", be32_to_cpu(e.crc)); | |
129 | + else | |
130 | + printf("CRC: %08x (should be %08x)\n", | |
131 | + be32_to_cpu(e.crc), crc); | |
132 | + | |
133 | +#ifdef DEBUG | |
134 | + printf("EEPROM dump: (0x%x bytes)\n", sizeof(e)); | |
135 | + for (i = 0; i < sizeof(e); i++) { | |
136 | + if ((i % 16) == 0) | |
137 | + printf("%02X: ", i); | |
138 | + printf("%02X ", ((u8 *)&e)[i]); | |
139 | + if (((i % 16) == 15) || (i == sizeof(e) - 1)) | |
140 | + printf("\n"); | |
141 | + } | |
142 | +#endif | |
143 | +} | |
144 | + | |
145 | +/** | |
146 | + * read_eeprom - read the EEPROM into memory | |
147 | + */ | |
148 | +static int read_eeprom(void) | |
149 | +{ | |
150 | + int ret; | |
151 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
152 | + unsigned int bus; | |
153 | +#endif | |
154 | + | |
155 | + if (has_been_read) | |
156 | + return 0; | |
157 | + | |
158 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
159 | + bus = i2c_get_bus_num(); | |
160 | + i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM); | |
161 | +#endif | |
162 | + | |
163 | + ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, | |
164 | + (void *)&e, sizeof(e)); | |
165 | + | |
166 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
167 | + i2c_set_bus_num(bus); | |
168 | +#endif | |
169 | + | |
170 | +#ifdef DEBUG | |
171 | + show_eeprom(); | |
172 | +#endif | |
173 | + | |
174 | + has_been_read = (ret == 0) ? 1 : 0; | |
175 | + | |
176 | + return ret; | |
177 | +} | |
178 | + | |
179 | +/** | |
180 | + * update_crc - update the CRC | |
181 | + * | |
182 | + * This function should be called after each update to the EEPROM structure, | |
183 | + * to make sure the CRC is always correct. | |
184 | + */ | |
185 | +static void update_crc(void) | |
186 | +{ | |
187 | + u32 crc; | |
188 | + | |
189 | + crc = crc32(0, (void *)&e, sizeof(e) - 4); | |
190 | + e.crc = cpu_to_be32(crc); | |
191 | +} | |
192 | + | |
193 | +/** | |
194 | + * prog_eeprom - write the EEPROM from memory | |
195 | + */ | |
196 | +static int prog_eeprom(void) | |
197 | +{ | |
198 | + int ret = 0; | |
199 | + int i; | |
200 | + void *p; | |
201 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
202 | + unsigned int bus; | |
203 | +#endif | |
204 | + | |
205 | + /* Set the reserved values to 0xFF */ | |
206 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
207 | + e.res_0 = 0xFF; | |
208 | + memset(e.res_1, 0xFF, sizeof(e.res_1)); | |
209 | +#else | |
210 | + memset(e.res_0, 0xFF, sizeof(e.res_0)); | |
211 | +#endif | |
212 | + update_crc(); | |
213 | + | |
214 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
215 | + bus = i2c_get_bus_num(); | |
216 | + i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM); | |
217 | +#endif | |
218 | + | |
219 | + /* | |
220 | + * The AT24C02 datasheet says that data can only be written in page | |
221 | + * mode, which means 8 bytes at a time, and it takes up to 5ms to | |
222 | + * complete a given write. | |
223 | + */ | |
224 | + for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) { | |
225 | + ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, | |
226 | + p, min((int)(sizeof(e) - i), 8)); | |
227 | + if (ret) | |
228 | + break; | |
229 | + udelay(5000); /* 5ms write cycle timing */ | |
230 | + } | |
231 | + | |
232 | + if (!ret) { | |
233 | + /* Verify the write by reading back the EEPROM and comparing */ | |
234 | + struct eeprom e2; | |
235 | + | |
236 | + ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, | |
237 | + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (void *)&e2, sizeof(e2)); | |
238 | + if (!ret && memcmp(&e, &e2, sizeof(e))) | |
239 | + ret = -1; | |
240 | + } | |
241 | + | |
242 | +#ifdef CONFIG_SYS_EEPROM_BUS_NUM | |
243 | + i2c_set_bus_num(bus); | |
244 | +#endif | |
245 | + | |
246 | + if (ret) { | |
247 | + printf("Programming failed.\n"); | |
248 | + has_been_read = 0; | |
249 | + return -1; | |
250 | + } | |
251 | + | |
252 | + printf("Programming passed.\n"); | |
253 | + return 0; | |
254 | +} | |
255 | + | |
256 | +/** | |
257 | + * h2i - converts hex character into a number | |
258 | + * | |
259 | + * This function takes a hexadecimal character (e.g. '7' or 'C') and returns | |
260 | + * the integer equivalent. | |
261 | + */ | |
262 | +static inline u8 h2i(char p) | |
263 | +{ | |
264 | + if ((p >= '0') && (p <= '9')) | |
265 | + return p - '0'; | |
266 | + | |
267 | + if ((p >= 'A') && (p <= 'F')) | |
268 | + return (p - 'A') + 10; | |
269 | + | |
270 | + if ((p >= 'a') && (p <= 'f')) | |
271 | + return (p - 'a') + 10; | |
272 | + | |
273 | + return 0; | |
274 | +} | |
275 | + | |
276 | +/** | |
277 | + * set_date - stores the build date into the EEPROM | |
278 | + * | |
279 | + * This function takes a pointer to a string in the format "YYMMDDhhmmss" | |
280 | + * (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string, | |
281 | + * and stores it in the build date field of the EEPROM local copy. | |
282 | + */ | |
283 | +static void set_date(const char *string) | |
284 | +{ | |
285 | + unsigned int i; | |
286 | + | |
287 | + if (strlen(string) != 12) { | |
288 | + printf("Usage: mac date YYMMDDhhmmss\n"); | |
289 | + return; | |
290 | + } | |
291 | + | |
292 | + for (i = 0; i < 6; i++) | |
293 | + e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]); | |
294 | + | |
295 | + update_crc(); | |
296 | +} | |
297 | + | |
298 | +/** | |
299 | + * set_mac_address - stores a MAC address into the EEPROM | |
300 | + * | |
301 | + * This function takes a pointer to MAC address string | |
302 | + * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and | |
303 | + * stores it in one of the MAC address fields of the EEPROM local copy. | |
304 | + */ | |
305 | +static void set_mac_address(unsigned int index, const char *string) | |
306 | +{ | |
307 | + char *p = (char *) string; | |
308 | + unsigned int i; | |
309 | + | |
310 | + if ((index >= MAX_NUM_PORTS) || !string) { | |
311 | + printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n"); | |
312 | + return; | |
313 | + } | |
314 | + | |
315 | + for (i = 0; *p && (i < 6); i++) { | |
316 | + e.mac[index][i] = simple_strtoul(p, &p, 16); | |
317 | + if (*p == ':') | |
318 | + p++; | |
319 | + } | |
320 | + | |
321 | + update_crc(); | |
322 | +} | |
323 | + | |
324 | +int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
325 | +{ | |
326 | + char cmd; | |
327 | + | |
328 | + if (argc == 1) { | |
329 | + show_eeprom(); | |
330 | + return 0; | |
331 | + } | |
332 | + | |
333 | + cmd = argv[1][0]; | |
334 | + | |
335 | + if (cmd == 'r') { | |
336 | + read_eeprom(); | |
337 | + return 0; | |
338 | + } | |
339 | + | |
340 | + if (cmd == 'i') { | |
341 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
342 | + memcpy(e.id, "NXID", sizeof(e.id)); | |
343 | + e.version = cpu_to_be32(NXID_VERSION); | |
344 | +#else | |
345 | + memcpy(e.id, "CCID", sizeof(e.id)); | |
346 | +#endif | |
347 | + update_crc(); | |
348 | + return 0; | |
349 | + } | |
350 | + | |
351 | + if (!is_valid) { | |
352 | + printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n"); | |
353 | + return 0; | |
354 | + } | |
355 | + | |
356 | + if (argc == 2) { | |
357 | + switch (cmd) { | |
358 | + case 's': /* save */ | |
359 | + prog_eeprom(); | |
360 | + break; | |
361 | + default: | |
362 | + return cmd_usage(cmdtp); | |
363 | + } | |
364 | + | |
365 | + return 0; | |
366 | + } | |
367 | + | |
368 | + /* We know we have at least one parameter */ | |
369 | + | |
370 | + switch (cmd) { | |
371 | + case 'n': /* serial number */ | |
372 | + memset(e.sn, 0, sizeof(e.sn)); | |
373 | + strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1); | |
374 | + update_crc(); | |
375 | + break; | |
376 | + case 'e': /* errata */ | |
377 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
378 | + memset(e.errata, 0, 5); | |
379 | + strncpy((char *)e.errata, argv[2], 4); | |
380 | +#else | |
381 | + e.errata[0] = argv[2][0]; | |
382 | + e.errata[1] = argv[2][1]; | |
383 | +#endif | |
384 | + update_crc(); | |
385 | + break; | |
386 | + case 'd': /* date BCD format YYMMDDhhmmss */ | |
387 | + set_date(argv[2]); | |
388 | + break; | |
389 | + case 'p': /* MAC table size */ | |
390 | + e.mac_count = simple_strtoul(argv[2], NULL, 16); | |
391 | + update_crc(); | |
392 | + break; | |
393 | + case '0' ... '9': /* "mac 0" through "mac 22" */ | |
394 | + set_mac_address(simple_strtoul(argv[1], NULL, 10), argv[2]); | |
395 | + break; | |
396 | + case 'h': /* help */ | |
397 | + default: | |
398 | + return cmd_usage(cmdtp); | |
399 | + } | |
400 | + | |
401 | + return 0; | |
402 | +} | |
403 | + | |
404 | +/** | |
405 | + * mac_read_from_eeprom - read the MAC addresses from EEPROM | |
406 | + * | |
407 | + * This function reads the MAC addresses from EEPROM and sets the | |
408 | + * appropriate environment variables for each one read. | |
409 | + * | |
410 | + * The environment variables are only set if they haven't been set already. | |
411 | + * This ensures that any user-saved variables are never overwritten. | |
412 | + * | |
413 | + * This function must be called after relocation. | |
414 | + * | |
415 | + * For NXID v1 EEPROMs, we support loading and up-converting the older NXID v0 | |
416 | + * format. In a v0 EEPROM, there are only eight MAC addresses and the CRC is | |
417 | + * located at a different offset. | |
418 | + */ | |
419 | +int mac_read_from_eeprom(void) | |
420 | +{ | |
421 | + unsigned int i; | |
422 | + u32 crc, crc_offset = offsetof(struct eeprom, crc); | |
423 | + u32 *crcp; /* Pointer to the CRC in the data read from the EEPROM */ | |
424 | + | |
425 | + puts("EEPROM: "); | |
426 | + | |
427 | + if (read_eeprom()) { | |
428 | + printf("Read failed.\n"); | |
429 | + return 0; | |
430 | + } | |
431 | + | |
432 | + if (!is_valid) { | |
433 | + printf("Invalid ID (%02x %02x %02x %02x)\n", | |
434 | + e.id[0], e.id[1], e.id[2], e.id[3]); | |
435 | + return 0; | |
436 | + } | |
437 | + | |
438 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
439 | + /* | |
440 | + * If we've read an NXID v0 EEPROM, then we need to set the CRC offset | |
441 | + * to where it is in v0. | |
442 | + */ | |
443 | + if (e.version == 0) | |
444 | + crc_offset = 0x72; | |
445 | +#endif | |
446 | + | |
447 | + crc = crc32(0, (void *)&e, crc_offset); | |
448 | + crcp = (void *)&e + crc_offset; | |
449 | + if (crc != be32_to_cpu(*crcp)) { | |
450 | + printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc)); | |
451 | + return 0; | |
452 | + } | |
453 | + | |
454 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
455 | + /* | |
456 | + * MAC address #9 in v1 occupies the same position as the CRC in v0. | |
457 | + * Erase it so that it's not mistaken for a MAC address. We'll | |
458 | + * update the CRC later. | |
459 | + */ | |
460 | + if (e.version == 0) | |
461 | + memset(e.mac[8], 0xff, 6); | |
462 | +#endif | |
463 | + | |
464 | + for (i = 0; i < min(e.mac_count, (u8)MAX_NUM_PORTS); i++) { | |
465 | + if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) && | |
466 | + memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) { | |
467 | + char ethaddr[18]; | |
468 | + char enetvar[9]; | |
469 | + | |
470 | + sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", | |
471 | + e.mac[i][0], | |
472 | + e.mac[i][1], | |
473 | + e.mac[i][2], | |
474 | + e.mac[i][3], | |
475 | + e.mac[i][4], | |
476 | + e.mac[i][5]); | |
477 | + sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); | |
478 | + /* Only initialize environment variables that are blank | |
479 | + * (i.e. have not yet been set) | |
480 | + */ | |
481 | + if (!getenv(enetvar)) | |
482 | + setenv(enetvar, ethaddr); | |
483 | + } | |
484 | + } | |
485 | + | |
486 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
487 | + printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3], | |
488 | + be32_to_cpu(e.version)); | |
489 | +#else | |
490 | + printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]); | |
491 | +#endif | |
492 | + | |
493 | +#ifdef CONFIG_SYS_I2C_EEPROM_NXID | |
494 | + /* | |
495 | + * Now we need to upconvert the data into v1 format. We do this last so | |
496 | + * that at boot time, U-Boot will still say "NXID v0". | |
497 | + */ | |
498 | + if (e.version == 0) { | |
499 | + e.version = cpu_to_be32(NXID_VERSION); | |
500 | + update_crc(); | |
501 | + } | |
502 | +#endif | |
503 | + | |
504 | + return 0; | |
505 | +} | |
506 | + | |
507 | +#ifdef CONFIG_SYS_I2C_EEPROM_CCID | |
508 | + | |
509 | +/** | |
510 | + * get_cpu_board_revision - get the CPU board revision on 85xx boards | |
511 | + * | |
512 | + * Read the EEPROM to determine the board revision. | |
513 | + * | |
514 | + * This function is called before relocation, so we need to read a private | |
515 | + * copy of the EEPROM into a local variable on the stack. | |
516 | + * | |
517 | + * Also, we assume that CONFIG_SYS_EEPROM_BUS_NUM == CONFIG_SYS_SPD_BUS_NUM. The global | |
518 | + * variable i2c_bus_num must be compile-time initialized to CONFIG_SYS_SPD_BUS_NUM, | |
519 | + * so that the SPD code will work. This means that all pre-relocation I2C | |
520 | + * operations can only occur on the CONFIG_SYS_SPD_BUS_NUM bus. So if | |
521 | + * CONFIG_SYS_EEPROM_BUS_NUM != CONFIG_SYS_SPD_BUS_NUM, then we can't read the EEPROM when | |
522 | + * this function is called. Oh well. | |
523 | + */ | |
524 | +unsigned int get_cpu_board_revision(void) | |
525 | +{ | |
526 | + struct board_eeprom { | |
527 | + u32 id; /* 0x00 - 0x03 EEPROM Tag 'CCID' */ | |
528 | + u8 major; /* 0x04 Board revision, major */ | |
529 | + u8 minor; /* 0x05 Board revision, minor */ | |
530 | + } be; | |
531 | + | |
532 | + i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN, | |
533 | + (void *)&be, sizeof(be)); | |
534 | + | |
535 | + if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D')) | |
536 | + return MPC85XX_CPU_BOARD_REV(0, 0); | |
537 | + | |
538 | + if ((be.major == 0xff) && (be.minor == 0xff)) | |
539 | + return MPC85XX_CPU_BOARD_REV(0, 0); | |
540 | + | |
541 | + return MPC85XX_CPU_BOARD_REV(be.major, be.minor); | |
542 | +} | |
543 | +#endif |
board/embedian/smarcfimx7/Kconfig
board/embedian/smarcfimx7/MAINTAINERS
1 | +SMARC-FiMX7 SOLO/DUAL CORE SMARC 2.0 COMPUTER ON MODULE | |
2 | +M: Eric Lee <eric.lee@embedian.com> | |
3 | +S: Maintained | |
4 | +F: board/embedian/smarcfimx7 | |
5 | +F: include/configs/smarcfimx7.h | |
6 | +F: include/configs/mx7smarc_common.h | |
7 | +F: configs/smarcfimx7d_ser0_defconfig | |
8 | +F: configs/smarcfimx7d_ser1_defconfig | |
9 | +F: configs/smarcfimx7d_ser2_defconfig | |
10 | +F: configs/smarcfimx7d_ser3_defconfig | |
11 | +F: configs/smarcfimx7s_ser0_defconfig | |
12 | +F: configs/smarcfimx7s_ser1_defconfig | |
13 | +F: configs/smarcfimx7s_ser2_defconfig | |
14 | +F: configs/smarcfimx7s_ser3_defconfig |
board/embedian/smarcfimx7/Makefile
board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + * | |
6 | + * Refer docs/README.imxmage for more details about how-to configure | |
7 | + * and create imximage boot image | |
8 | + * | |
9 | + * The syntax is taken as close as possible with the kwbimage | |
10 | + */ | |
11 | + | |
12 | +#define __ASSEMBLY__ | |
13 | +#include <config.h> | |
14 | + | |
15 | +/* image version */ | |
16 | + | |
17 | +IMAGE_VERSION 2 | |
18 | + | |
19 | +/* | |
20 | + * Boot Device : one of | |
21 | + * spi/sd/nand/onenand, qspi/nor | |
22 | + */ | |
23 | + | |
24 | +BOOT_FROM spi | |
25 | + | |
26 | +/* | |
27 | + * Secure boot support | |
28 | + */ | |
29 | +#ifdef CONFIG_SECURE_BOOT | |
30 | +CSF CONFIG_CSF_SIZE | |
31 | +#endif | |
32 | + | |
33 | +/* | |
34 | + * Device Configuration Data (DCD) | |
35 | + * | |
36 | + * Each entry must have the format: | |
37 | + * Addr-type Address Value | |
38 | + * | |
39 | + * where: | |
40 | + * Addr-type register length (1,2 or 4 bytes) | |
41 | + * Address absolute address of the register | |
42 | + * value value to be stored in the register | |
43 | + */ | |
44 | + | |
45 | +/* IOMUXC_GPR_GPR1 */ | |
46 | +DATA 4 0x30340004 0x4F400005 | |
47 | +/* Clear then set bit30 to ensure exit from DDR retention */ | |
48 | +DATA 4 0x30360388 0x40000000 | |
49 | +DATA 4 0x30360384 0x40000000 | |
50 | +/* SRC_DDRC_RCR */ | |
51 | +DATA 4 0x30391000 0x00000002 | |
52 | +/* DDRC_MSTR */ | |
53 | +DATA 4 0x307a0000 0x01040001 | |
54 | +/* DDRC_DFIUPD0 */ | |
55 | +DATA 4 0x307a01a0 0x80400003 | |
56 | +/* DDRC_DFIUPD1 */ | |
57 | +DATA 4 0x307a01a4 0x00100020 | |
58 | +/* DDRC_DFIUPD2 */ | |
59 | +DATA 4 0x307a01a8 0x80100004 | |
60 | +/* DDRC_RFSHTMG */ | |
61 | +DATA 4 0x307a0064 0x00400046 | |
62 | +/* DDRC_MP_PCTRL_0 */ | |
63 | +DATA 4 0x307a0490 0x00000001 | |
64 | +/* DDRC_INIT0 */ | |
65 | +DATA 4 0x307a00d0 0x00020083 | |
66 | +/* DDRC_INIT1 */ | |
67 | +DATA 4 0x307a00d4 0x00690000 | |
68 | +/* DDRC_INIT3 MR0/MR1 */ | |
69 | +DATA 4 0x307a00dc 0x09300004 | |
70 | +/* DDRC_INIT4 MR2/MR3 */ | |
71 | +DATA 4 0x307a00e0 0x04080000 | |
72 | +/* DDRC_INIT5 */ | |
73 | +DATA 4 0x307a00e4 0x00100004 | |
74 | +/* DDRC_RANKCTL */ | |
75 | +DATA 4 0x307a00f4 0x0000033f | |
76 | +/* DDRC_DRAMTMG0 */ | |
77 | +DATA 4 0x307a0100 0x09081109 | |
78 | +/* DDRC_DRAMTMG1 */ | |
79 | +DATA 4 0x307a0104 0x0007020d | |
80 | +/* DDRC_DRAMTMG2 */ | |
81 | +DATA 4 0x307a0108 0x03040407 | |
82 | +/* DDRC_DRAMTMG3 */ | |
83 | +DATA 4 0x307a010c 0x00002006 | |
84 | +/* DDRC_DRAMTMG4 */ | |
85 | +DATA 4 0x307a0110 0x04020205 | |
86 | +/* DDRC_DRAMTMG5 */ | |
87 | +DATA 4 0x307a0114 0x03030202 | |
88 | +/* DDRC_DRAMTMG8 */ | |
89 | +DATA 4 0x307a0120 0x00000803 | |
90 | +/* DDRC_ZQCTL0 */ | |
91 | +DATA 4 0x307a0180 0x00800020 | |
92 | +/* DDRC_ZQCTL1 */ | |
93 | +DATA 4 0x307a0184 0x02001000 | |
94 | +/* DDRC_DFITMG0 */ | |
95 | +DATA 4 0x307a0190 0x02098204 | |
96 | +/* DDRC_DFITMG1 */ | |
97 | +DATA 4 0x307a0194 0x00030303 | |
98 | +/* DDRC_ADDRMAP0 */ | |
99 | +DATA 4 0x307a0200 0x00000016 | |
100 | +/* DDRC_ADDRMAP1 */ | |
101 | +DATA 4 0x307a0204 0x00171717 | |
102 | +/* DDRC_ADDRMAP4 */ | |
103 | +DATA 4 0x307a0210 0x00000f0f | |
104 | +/* DDRC_ADDRMAP5 */ | |
105 | +DATA 4 0x307a0214 0x04040404 | |
106 | +/* DDRC_ADDRMAP6 */ | |
107 | +DATA 4 0x307a0218 0x0f040404 | |
108 | +/* DDRC_ODTCFG */ | |
109 | +DATA 4 0x307a0240 0x06000604 | |
110 | +/* DDRC_ODTMAP */ | |
111 | +DATA 4 0x307a0244 0x00000001 | |
112 | +/* SRC_DDRC_RCR */ | |
113 | +DATA 4 0x30391000 0x00000000 | |
114 | +/* DDR_PHY_PHY_CON0 */ | |
115 | +DATA 4 0x30790000 0x17420f40 | |
116 | +/* DDR_PHY_PHY_CON1 */ | |
117 | +DATA 4 0x30790004 0x10210100 | |
118 | +/* DDR_PHY_PHY_CON4 */ | |
119 | +DATA 4 0x30790010 0x00060807 | |
120 | +/* DDR_PHY_MDLL_CON0 */ | |
121 | +DATA 4 0x307900b0 0x1010007e | |
122 | +/* DDR_PHY_DRVDS_CON0 */ | |
123 | +DATA 4 0x3079009c 0x00000d6e | |
124 | +/* DDR_PHY_OFFSET_RD_CON0 */ | |
125 | +DATA 4 0x30790020 0x0a0a0a0a | |
126 | +/* DDR_PHY_OFFSET_WR_CON0 */ | |
127 | +DATA 4 0x30790030 0x04040404 | |
128 | +/* DDR_PHY_OFFSETD_CON0 */ | |
129 | +DATA 4 0x30790050 0x01000010 | |
130 | +DATA 4 0x30790050 0x00000010 | |
131 | + | |
132 | +/* DDR_PHY_ZQ_CON0 */ | |
133 | +DATA 4 0x307900c0 0x0e407304 | |
134 | +DATA 4 0x307900c0 0x0e447304 | |
135 | +DATA 4 0x307900c0 0x0e447306 | |
136 | + | |
137 | +/* DDR_PHY_ZQ_CON1 */ | |
138 | +CHECK_BITS_SET 4 0x307900c4 0x1 | |
139 | + | |
140 | +/* DDR_PHY_ZQ_CON0 */ | |
141 | +DATA 4 0x307900c0 0x0e447304 | |
142 | +DATA 4 0x307900c0 0x0e407304 | |
143 | + | |
144 | +/* CCM_CCGRn */ | |
145 | +DATA 4 0x30384130 0x00000000 | |
146 | +/* IOMUXC_GPR_GPR8 */ | |
147 | +DATA 4 0x30340020 0x00000178 | |
148 | +/* CCM_CCGRn */ | |
149 | +DATA 4 0x30384130 0x00000002 | |
150 | +/* DDR_PHY_LP_CON0 */ | |
151 | +DATA 4 0x30790018 0x0000000f | |
152 | + | |
153 | +/* DDRC_STAT */ | |
154 | +CHECK_BITS_SET 4 0x307a0004 0x1 |
board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg
1 | +/* | |
2 | + * Copyright (C) 2015 Freescale Semiconductor, Inc. | |
3 | + * 2015 Toradex AG | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + * | |
7 | + * Refer doc/README.imximage for more details about how-to configure | |
8 | + * and create imximage boot image | |
9 | + * | |
10 | + * The syntax is taken as close as possible with the kwbimage | |
11 | + */ | |
12 | + | |
13 | +#define __ASSEMBLY__ | |
14 | +#include <config.h> | |
15 | + | |
16 | +/* image version */ | |
17 | + | |
18 | +IMAGE_VERSION 2 | |
19 | + | |
20 | +/* | |
21 | + * Boot Device : spi | |
22 | + */ | |
23 | + | |
24 | +BOOT_FROM spi | |
25 | + | |
26 | +/* | |
27 | + * Secure boot support | |
28 | + */ | |
29 | +#ifdef CONFIG_SECURE_BOOT | |
30 | +CSF CONFIG_CSF_SIZE | |
31 | +#endif | |
32 | + | |
33 | +/* | |
34 | + * Device Configuration Data (DCD) | |
35 | + * | |
36 | + * Each entry must have the format: | |
37 | + * Addr-type Address Value | |
38 | + * | |
39 | + * where: | |
40 | + * Addr-type register length (1,2 or 4 bytes) | |
41 | + * Address absolute address of the register | |
42 | + * value value to be stored in the register | |
43 | + */ | |
44 | + | |
45 | +/* IOMUXC_GPR_GPR1 */ | |
46 | +DATA 4 0x30340004 0x4F400005 | |
47 | + | |
48 | +/* DDR3L */ | |
49 | +/* assuming MEMC_FREQ_RATIO = 2 */ | |
50 | +/* SRC_DDRC_RCR */ | |
51 | +DATA 4 0x30391000 0x00000002 | |
52 | +/* DDRC_MSTR */ | |
53 | +DATA 4 0x307a0000 0x01040001 | |
54 | +/* DDRC_DFIUPD0 */ | |
55 | +DATA 4 0x307a01a0 0x80400003 | |
56 | +/* DDRC_DFIUPD1 */ | |
57 | +DATA 4 0x307a01a4 0x00100020 | |
58 | +/* DDRC_DFIUPD2 */ | |
59 | +DATA 4 0x307a01a8 0x80100004 | |
60 | +/* DDRC_RFSHTMG */ | |
61 | +DATA 4 0x307a0064 0x00400045 | |
62 | +/* DDRC_MP_PCTRL_0 */ | |
63 | +DATA 4 0x307a0490 0x00000001 | |
64 | +/* DDRC_INIT0 */ | |
65 | +DATA 4 0x307a00d0 0x00020083 | |
66 | +/* DDRC_INIT1 */ | |
67 | +DATA 4 0x307a00d4 0x00690000 | |
68 | +/* DDRC_INIT3 MR0/MR1 */ | |
69 | +DATA 4 0x307a00dc 0x09300004 | |
70 | +/* DDRC_INIT4 MR2/MR3 */ | |
71 | +DATA 4 0x307a00e0 0x04480000 | |
72 | +/* DDRC_INIT5 */ | |
73 | +DATA 4 0x307a00e4 0x00100004 | |
74 | +/* DDRC_RANKCTL */ | |
75 | +DATA 4 0x307a00f4 0x0000033f | |
76 | +/* DDRC_DRAMTMG0 */ | |
77 | +DATA 4 0x307a0100 0x090b090a | |
78 | +/* DDRC_DRAMTMG1 */ | |
79 | +DATA 4 0x307a0104 0x000d020d | |
80 | +/* DDRC_DRAMTMG2 */ | |
81 | +DATA 4 0x307a0108 0x03040307 | |
82 | +/* DDRC_DRAMTMG3 */ | |
83 | +DATA 4 0x307a010c 0x00002006 | |
84 | +/* DDRC_DRAMTMG4 */ | |
85 | +DATA 4 0x307a0110 0x04020205 | |
86 | +/* DDRC_DRAMTMG5 */ | |
87 | +DATA 4 0x307a0114 0x03030202 | |
88 | +/* DDRC_DRAMTMG8 */ | |
89 | +DATA 4 0x307a0120 0x00000803 | |
90 | +/* DDRC_ZQCTL0 */ | |
91 | +DATA 4 0x307a0180 0x00800020 | |
92 | +/* DDRC_ZQCTL1 */ | |
93 | +DATA 4 0x307a0184 0x02001000 | |
94 | +/* DDRC_DFITMG0 */ | |
95 | +DATA 4 0x307a0190 0x02098204 | |
96 | +/* DDRC_DFITMG1 */ | |
97 | +DATA 4 0x307a0194 0x00030303 | |
98 | +/* DDRC_ADDRMAP0 */ | |
99 | +DATA 4 0x307a0200 0x0000001f | |
100 | +/* DDRC_ADDRMAP1 */ | |
101 | +DATA 4 0x307a0204 0x00080808 | |
102 | +/* DDRC_ADDRMAP5 */ | |
103 | +DATA 4 0x307a0214 0x07070707 | |
104 | +/* DDRC_ADDRMAP6 */ | |
105 | +DATA 4 0x307a0218 0x07070707 | |
106 | +/* DDRC_ODTCFG */ | |
107 | +DATA 4 0x307a0240 0x06000601 | |
108 | +/* DDRC_ODTMAP */ | |
109 | +DATA 4 0x307a0244 0x00000011 | |
110 | +/* SRC_DDRC_RCR */ | |
111 | +DATA 4 0x30391000 0x00000000 | |
112 | +/* DDR_PHY_PHY_CON0 */ | |
113 | +DATA 4 0x30790000 0x17420f40 | |
114 | +/* DDR_PHY_PHY_CON1 */ | |
115 | +DATA 4 0x30790004 0x10210100 | |
116 | +/* DDR_PHY_PHY_CON4 */ | |
117 | +DATA 4 0x30790010 0x00060807 | |
118 | +/* DDR_PHY_MDLL_CON0 */ | |
119 | +DATA 4 0x307900b0 0x1010007e | |
120 | +/* DDR_PHY_DRVDS_CON0 */ | |
121 | +DATA 4 0x3079009c 0x00000d6e | |
122 | +/* DDR_PHY_OFFSET_RD_CON0 */ | |
123 | +DATA 4 0x30790020 0x0a0a0a0a | |
124 | +/* DDR_PHY_OFFSET_WR_CON0 */ | |
125 | +DATA 4 0x30790030 0x04040404 | |
126 | +/* DDR_PHY_CMD_SDLL_CON0 */ | |
127 | +DATA 4 0x30790050 0x01000010 | |
128 | +DATA 4 0x30790050 0x00000010 | |
129 | + | |
130 | +/* DDR_PHY_ZQ_CON0 */ | |
131 | +DATA 4 0x307900c0 0x0e407304 | |
132 | +DATA 4 0x307900c0 0x0e447304 | |
133 | +DATA 4 0x307900c0 0x0e447306 | |
134 | +/* DDR_PHY_ZQ_CON1 */ | |
135 | +CHECK_BITS_SET 4 0x307900c4 0x1 | |
136 | +/* DDR_PHY_ZQ_CON0 */ | |
137 | +DATA 4 0x307900c0 0x0e447304 | |
138 | +DATA 4 0x307900c0 0x0e407304 | |
139 | + | |
140 | +/* CCM_CCGRn */ | |
141 | +DATA 4 0x30384130 0x00000000 | |
142 | +/* IOMUXC_GPR_GPR8 */ | |
143 | +DATA 4 0x30340020 0x00000178 | |
144 | +/* CCM_CCGRn */ | |
145 | +DATA 4 0x30384130 0x00000002 | |
146 | +/* DDR_PHY_LP_CON0 */ | |
147 | +DATA 4 0x30790018 0x0000000f | |
148 | + | |
149 | +/* DDRC_STAT */ | |
150 | +CHECK_BITS_SET 4 0x307a0004 0x1 |
board/embedian/smarcfimx7/pfuze.h
1 | +/* | |
2 | + * Copyright 2014 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#ifndef __PFUZE_BOARD_HELPER__ | |
8 | +#define __PFUZE_BOARD_HELPER__ | |
9 | + | |
10 | +struct pmic *pfuze_common_init(unsigned char i2cbus); | |
11 | +int pfuze_mode_init(struct pmic *p, u32 mode); | |
12 | + | |
13 | +#endif |
board/embedian/smarcfimx7/plugin.S
1 | +/* | |
2 | + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <config.h> | |
8 | + | |
9 | +/* DDR script */ | |
10 | +.macro imx7d_ddrphy_latency_setting | |
11 | + ldr r2, =ANATOP_BASE_ADDR | |
12 | + ldr r3, [r2, #0x800] | |
13 | + and r3, r3, #0xFF | |
14 | + cmp r3, #0x11 | |
15 | + bne NO_DELAY | |
16 | + | |
17 | + /*TO 1.1*/ | |
18 | + ldr r1, =0x00000dee | |
19 | + str r1, [r0, #0x9c] | |
20 | + ldr r1, =0x18181818 | |
21 | + str r1, [r0, #0x7c] | |
22 | + ldr r1, =0x18181818 | |
23 | + str r1, [r0, #0x80] | |
24 | + ldr r1, =0x40401818 | |
25 | + str r1, [r0, #0x84] | |
26 | + ldr r1, =0x00000040 | |
27 | + str r1, [r0, #0x88] | |
28 | + ldr r1, =0x40404040 | |
29 | + str r1, [r0, #0x6c] | |
30 | + b TUNE_END | |
31 | + | |
32 | +NO_DELAY: | |
33 | + /*TO 1.0*/ | |
34 | + ldr r1, =0x00000d6e | |
35 | + str r1, [r0, #0x9c] | |
36 | + | |
37 | +TUNE_END: | |
38 | +.endm | |
39 | + | |
40 | +.macro imx7d_ddr_freq_setting | |
41 | + ldr r2, =ANATOP_BASE_ADDR | |
42 | + ldr r3, [r2, #0x800] | |
43 | + and r3, r3, #0xFF | |
44 | + cmp r3, #0x11 | |
45 | + bne FREQ_DEFAULT_533 | |
46 | + | |
47 | + /* Change to 400Mhz for TO1.1 */ | |
48 | + ldr r0, =ANATOP_BASE_ADDR | |
49 | + ldr r1, =0x70 | |
50 | + ldr r2, =0x00703021 | |
51 | + str r2, [r0, r1] | |
52 | + ldr r1, =0x90 | |
53 | + ldr r2, =0x0 | |
54 | + str r2, [r0, r1] | |
55 | + ldr r1, =0x70 | |
56 | + ldr r2, =0x00603021 | |
57 | + str r2, [r0, r1] | |
58 | + | |
59 | + ldr r3, =0x80000000 | |
60 | +wait_lock: | |
61 | + ldr r2, [r0, r1] | |
62 | + and r2, r3 | |
63 | + cmp r2, r3 | |
64 | + bne wait_lock | |
65 | + | |
66 | + ldr r0, =CCM_BASE_ADDR | |
67 | + ldr r1, =0x9880 | |
68 | + ldr r2, =0x1 | |
69 | + str r2, [r0, r1] | |
70 | + | |
71 | +FREQ_DEFAULT_533: | |
72 | +.endm | |
73 | + | |
74 | +.macro smarcfimx7_ddr_setting | |
75 | + imx7d_ddr_freq_setting | |
76 | + | |
77 | + /* Configure ocram_epdc */ | |
78 | + ldr r0, =IOMUXC_GPR_BASE_ADDR | |
79 | + ldr r1, =0x4f400005 | |
80 | + str r1, [r0, #0x4] | |
81 | + | |
82 | + /* clear/set bit30 of SNVS_MISC_CTRL to ensure exit from ddr retention */ | |
83 | + ldr r0, =ANATOP_BASE_ADDR | |
84 | + ldr r1, =(0x1 << 30) | |
85 | + str r1, [r0, #0x388] | |
86 | + str r1, [r0, #0x384] | |
87 | + | |
88 | + ldr r0, =SRC_BASE_ADDR | |
89 | + ldr r1, =0x2 | |
90 | + ldr r2, =0x1000 | |
91 | + str r1, [r0, r2] | |
92 | + | |
93 | + ldr r0, =DDRC_IPS_BASE_ADDR | |
94 | + ldr r1, =0x01040001 | |
95 | + str r1, [r0] | |
96 | + ldr r1, =0x80400003 | |
97 | + str r1, [r0, #0x1a0] | |
98 | + ldr r1, =0x00100020 | |
99 | + str r1, [r0, #0x1a4] | |
100 | + ldr r1, =0x80100004 | |
101 | + str r1, [r0, #0x1a8] | |
102 | + ldr r1, =0x00400046 | |
103 | + str r1, [r0, #0x64] | |
104 | + ldr r1, =0x1 | |
105 | + str r1, [r0, #0x490] | |
106 | + ldr r1, =0x00020001 | |
107 | + str r1, [r0, #0xd0] | |
108 | + ldr r1, =0x00690000 | |
109 | + str r1, [r0, #0xd4] | |
110 | + ldr r1, =0x09300004 | |
111 | + str r1, [r0, #0xdc] | |
112 | + ldr r1, =0x04080000 | |
113 | + str r1, [r0, #0xe0] | |
114 | + ldr r1, =0x00100004 | |
115 | + str r1, [r0, #0xe4] | |
116 | + ldr r1, =0x33f | |
117 | + str r1, [r0, #0xf4] | |
118 | + ldr r1, =0x09081109 | |
119 | + str r1, [r0, #0x100] | |
120 | + ldr r1, =0x0007020d | |
121 | + str r1, [r0, #0x104] | |
122 | + ldr r1, =0x03040407 | |
123 | + str r1, [r0, #0x108] | |
124 | + ldr r1, =0x00002006 | |
125 | + str r1, [r0, #0x10c] | |
126 | + ldr r1, =0x04020205 | |
127 | + str r1, [r0, #0x110] | |
128 | + ldr r1, =0x03030202 | |
129 | + str r1, [r0, #0x114] | |
130 | + ldr r1, =0x00000803 | |
131 | + str r1, [r0, #0x120] | |
132 | + ldr r1, =0x00800020 | |
133 | + str r1, [r0, #0x180] | |
134 | + ldr r1, =0x02000100 | |
135 | + str r1, [r0, #0x184] | |
136 | + ldr r1, =0x02098204 | |
137 | + str r1, [r0, #0x190] | |
138 | + ldr r1, =0x00030303 | |
139 | + str r1, [r0, #0x194] | |
140 | + | |
141 | + ldr r1, =0x00000016 | |
142 | + str r1, [r0, #0x200] | |
143 | + ldr r1, =0x00171717 | |
144 | + str r1, [r0, #0x204] | |
145 | + ldr r1, =0x04040404 | |
146 | + str r1, [r0, #0x214] | |
147 | + ldr r1, =0x0f040404 | |
148 | + str r1, [r0, #0x218] | |
149 | + | |
150 | + ldr r1, =0x06000604 | |
151 | + str r1, [r0, #0x240] | |
152 | + ldr r1, =0x00000001 | |
153 | + str r1, [r0, #0x244] | |
154 | + | |
155 | + ldr r0, =SRC_BASE_ADDR | |
156 | + mov r1, #0x0 | |
157 | + ldr r2, =0x1000 | |
158 | + str r1, [r0, r2] | |
159 | + | |
160 | + ldr r0, =DDRPHY_IPS_BASE_ADDR | |
161 | + ldr r1, =0x17420f40 | |
162 | + str r1, [r0] | |
163 | + ldr r1, =0x10210100 | |
164 | + str r1, [r0, #0x4] | |
165 | + ldr r1, =0x00060807 | |
166 | + str r1, [r0, #0x10] | |
167 | + ldr r1, =0x1010007e | |
168 | + str r1, [r0, #0xb0] | |
169 | + imx7d_ddrphy_latency_setting | |
170 | + ldr r1, =0x08080808 | |
171 | + str r1, [r0, #0x20] | |
172 | + ldr r1, =0x08080808 | |
173 | + str r1, [r0, #0x30] | |
174 | + ldr r1, =0x01000010 | |
175 | + str r1, [r0, #0x50] | |
176 | + | |
177 | + ldr r1, =0x0e407304 | |
178 | + str r1, [r0, #0xc0] | |
179 | + ldr r1, =0x0e447304 | |
180 | + str r1, [r0, #0xc0] | |
181 | + ldr r1, =0x0e447306 | |
182 | + str r1, [r0, #0xc0] | |
183 | + | |
184 | +wait_zq: | |
185 | + ldr r1, [r0, #0xc4] | |
186 | + tst r1, #0x1 | |
187 | + beq wait_zq | |
188 | + | |
189 | + ldr r1, =0x0e447304 | |
190 | + str r1, [r0, #0xc0] | |
191 | + ldr r1, =0x0e407304 | |
192 | + str r1, [r0, #0xc0] | |
193 | + | |
194 | + ldr r0, =CCM_BASE_ADDR | |
195 | + mov r1, #0x0 | |
196 | + ldr r2, =0x4130 | |
197 | + str r1, [r0, r2] | |
198 | + ldr r0, =IOMUXC_GPR_BASE_ADDR | |
199 | + mov r1, #0x178 | |
200 | + str r1, [r0, #0x20] | |
201 | + ldr r0, =CCM_BASE_ADDR | |
202 | + mov r1, #0x2 | |
203 | + ldr r2, =0x4130 | |
204 | + str r1, [r0, r2] | |
205 | + ldr r0, =DDRPHY_IPS_BASE_ADDR | |
206 | + ldr r1, =0x0000000f | |
207 | + str r1, [r0, #0x18] | |
208 | + | |
209 | + ldr r0, =DDRC_IPS_BASE_ADDR | |
210 | +wait_stat: | |
211 | + ldr r1, [r0, #0x4] | |
212 | + tst r1, #0x1 | |
213 | + beq wait_stat | |
214 | +.endm | |
215 | + | |
216 | +.macro imx7_clock_gating | |
217 | +.endm | |
218 | + | |
219 | +.macro imx7_qos_setting | |
220 | +.endm | |
221 | + | |
222 | +.macro smarcfimx7_ddr_setting | |
223 | + smarcfimx7_ddr_setting | |
224 | +.endm | |
225 | + | |
226 | +/* include the common plugin code here */ | |
227 | +#include <asm/arch/mx7_plugin.S> |
board/embedian/smarcfimx7/smarcfimx7.c
Changes suppressed. Click to show
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <asm/arch/clock.h> | |
8 | +#include <asm/arch/imx-regs.h> | |
9 | +#include <asm/arch/mx7-pins.h> | |
10 | +#include <asm/arch/sys_proto.h> | |
11 | +#include <asm/gpio.h> | |
12 | +#include <asm/imx-common/iomux-v3.h> | |
13 | +#include <asm/imx-common/boot_mode.h> | |
14 | +#include <asm/io.h> | |
15 | +#include <linux/sizes.h> | |
16 | +#include <common.h> | |
17 | +#include <fsl_esdhc.h> | |
18 | +#include <mmc.h> | |
19 | +#include <miiphy.h> | |
20 | +#include <netdev.h> | |
21 | +#include <power/pmic.h> | |
22 | +#include <power/pfuze3000_pmic.h> | |
23 | +#include "pfuze.h" | |
24 | +#include <pwm.h> | |
25 | +#include <i2c.h> | |
26 | +#include <asm/imx-common/mxc_i2c.h> | |
27 | +#include <asm/arch/crm_regs.h> | |
28 | +#include <usb.h> | |
29 | +#include <usb/ehci-fsl.h> | |
30 | +#if defined(CONFIG_MXC_EPDC) | |
31 | +#include <lcd.h> | |
32 | +#include <mxc_epdc_fb.h> | |
33 | +#endif | |
34 | +#include <asm/imx-common/video.h> | |
35 | + | |
36 | +#include "smarcfimx7.h" | |
37 | +#ifdef CONFIG_FSL_FASTBOOT | |
38 | +#include <fsl_fastboot.h> | |
39 | +#ifdef CONFIG_ANDROID_RECOVERY | |
40 | +#include <recovery.h> | |
41 | +#endif | |
42 | +#endif /*CONFIG_FSL_FASTBOOT*/ | |
43 | + | |
44 | +DECLARE_GLOBAL_DATA_PTR; | |
45 | + | |
46 | +#define UART_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | \ | |
47 | + PAD_CTL_PUS_PU100KOHM | PAD_CTL_HYS) | |
48 | + | |
49 | +#define USDHC_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ | |
50 | + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) | |
51 | + | |
52 | +#define ENET_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) | |
53 | +#define ENET_PAD_CTRL_MII (PAD_CTL_DSE_3P3V_32OHM) | |
54 | + | |
55 | +#define ENET_RX_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) | |
56 | + | |
57 | +#define I2C_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ | |
58 | + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU100KOHM) | |
59 | + | |
60 | +#define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_PU100KOHM | \ | |
61 | + PAD_CTL_DSE_3P3V_49OHM) | |
62 | + | |
63 | +#define SPI_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_FAST | PAD_CTL_HYS) | |
64 | + | |
65 | +#define BUTTON_PAD_CTRL (PAD_CTL_PUS_PU5KOHM | PAD_CTL_DSE_3P3V_98OHM) | |
66 | + | |
67 | +#define NAND_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) | |
68 | + | |
69 | +#define NAND_PAD_READY0_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUS_PU5KOHM) | |
70 | + | |
71 | +#define EPDC_PAD_CTRL 0x0 | |
72 | + | |
73 | +#define WEAK_PULLUP (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM | \ | |
74 | + PAD_CTL_HYS | PAD_CTL_SRE_SLOW) | |
75 | + | |
76 | +#ifdef CONFIG_SYS_I2C_MXC | |
77 | +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) | |
78 | +/* | |
79 | + * Read header information from EEPROM into global structure. | |
80 | + */ | |
81 | +static int read_eeprom(struct smarcfimx7_id *header) | |
82 | +{ | |
83 | + i2c_set_bus_num(1); | |
84 | + /* Check if baseboard eeprom is available */ | |
85 | + if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) { | |
86 | + puts("Could not probe the EEPROM; something fundamentally " | |
87 | + "wrong on the I2C bus.\n"); | |
88 | + return -ENODEV; | |
89 | + } | |
90 | + | |
91 | + /* read the eeprom using i2c */ | |
92 | + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header, | |
93 | + sizeof(struct smarcfimx7_id))) { | |
94 | + puts("Could not read the EEPROM; something fundamentally" | |
95 | + " wrong on the I2C bus.\n"); | |
96 | + return -EIO; | |
97 | + } | |
98 | + | |
99 | + if (header->magic != 0xEE3355AA) { | |
100 | + /* | |
101 | + * read the eeprom using i2c again, | |
102 | + * but use only a 1 byte address | |
103 | + */ | |
104 | + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header, | |
105 | + sizeof(struct smarcfimx7_id))) { | |
106 | + puts("Could not read the EEPROM; something " | |
107 | + "fundamentally wrong on the I2C bus.\n"); | |
108 | + return -EIO; | |
109 | + } | |
110 | + | |
111 | + if (header->magic != 0xEE3355AA) { | |
112 | + printf("Incorrect magic number (0x%x) in EEPROM\n", | |
113 | + header->magic); | |
114 | + return -EINVAL; | |
115 | + } | |
116 | + } | |
117 | + | |
118 | + return 0; | |
119 | +} | |
120 | + | |
121 | +/* I2C1 for PMIC (I2C_PM)*/ | |
122 | +static struct i2c_pads_info i2c_pad_info1 = { | |
123 | + .scl = { | |
124 | + .i2c_mode = MX7D_PAD_I2C1_SCL__I2C1_SCL | PC, | |
125 | + .gpio_mode = MX7D_PAD_I2C1_SCL__GPIO4_IO8 | PC, | |
126 | + .gp = IMX_GPIO_NR(4, 8), | |
127 | + }, | |
128 | + .sda = { | |
129 | + .i2c_mode = MX7D_PAD_I2C1_SDA__I2C1_SDA | PC, | |
130 | + .gpio_mode = MX7D_PAD_I2C1_SDA__GPIO4_IO9 | PC, | |
131 | + .gp = IMX_GPIO_NR(4, 9), | |
132 | + }, | |
133 | +}; | |
134 | + | |
135 | +/* I2C2 for I2C_GP */ | |
136 | +static struct i2c_pads_info i2c_pad_info2 = { | |
137 | + .scl = { | |
138 | + .i2c_mode = MX7D_PAD_I2C2_SCL__I2C2_SCL | PC, | |
139 | + .gpio_mode = MX7D_PAD_I2C2_SCL__GPIO4_IO10 | PC, | |
140 | + .gp = IMX_GPIO_NR(4, 10), | |
141 | + }, | |
142 | + .sda = { | |
143 | + .i2c_mode = MX7D_PAD_I2C2_SDA__I2C2_SDA | PC, | |
144 | + .gpio_mode = MX7D_PAD_I2C2_SDA__GPIO4_IO11 | PC, | |
145 | + .gp = IMX_GPIO_NR(4, 11), | |
146 | + }, | |
147 | +}; | |
148 | + | |
149 | +/* I2C3 for I2C_LCD */ | |
150 | +static struct i2c_pads_info i2c_pad_info3 = { | |
151 | + .scl = { | |
152 | + .i2c_mode = MX7D_PAD_I2C3_SCL__I2C3_SCL | PC, | |
153 | + .gpio_mode = MX7D_PAD_I2C3_SCL__GPIO4_IO12 | PC, | |
154 | + .gp = IMX_GPIO_NR(4, 12), | |
155 | + }, | |
156 | + .sda = { | |
157 | + .i2c_mode = MX7D_PAD_I2C3_SDA__I2C3_SDA | PC, | |
158 | + .gpio_mode = MX7D_PAD_I2C3_SDA__GPIO4_IO13 | PC, | |
159 | + .gp = IMX_GPIO_NR(4, 13), | |
160 | + }, | |
161 | +}; | |
162 | + | |
163 | +/* I2C4 for I2C_CAM1 */ | |
164 | +static struct i2c_pads_info i2c_pad_info4 = { | |
165 | + .scl = { | |
166 | + .i2c_mode = MX7D_PAD_I2C4_SCL__I2C4_SCL | PC, | |
167 | + .gpio_mode = MX7D_PAD_I2C4_SCL__GPIO4_IO14 | PC, | |
168 | + .gp = IMX_GPIO_NR(4, 14), | |
169 | + }, | |
170 | + .sda = { | |
171 | + .i2c_mode = MX7D_PAD_I2C4_SDA__I2C4_SDA | PC, | |
172 | + .gpio_mode = MX7D_PAD_I2C4_SDA__GPIO4_IO15 | PC, | |
173 | + .gp = IMX_GPIO_NR(4, 15), | |
174 | + }, | |
175 | +}; | |
176 | +#endif | |
177 | + | |
178 | +int dram_init(void) | |
179 | +{ | |
180 | + gd->ram_size = PHYS_SDRAM_SIZE; | |
181 | + | |
182 | + return 0; | |
183 | +} | |
184 | + | |
185 | +static iomux_v3_cfg_t const wdog_pads[] = { | |
186 | + MX7D_PAD_ENET1_RX_CLK__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL), | |
187 | +}; | |
188 | + | |
189 | +/* SER0/UART6 */ | |
190 | +static iomux_v3_cfg_t const uart6_pads[] = { | |
191 | + MX7D_PAD_EPDC_DATA09__UART6_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
192 | + MX7D_PAD_EPDC_DATA08__UART6_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
193 | + MX7D_PAD_EPDC_DATA10__UART6_DTE_CTS | MUX_PAD_CTRL(UART_PAD_CTRL), | |
194 | + MX7D_PAD_EPDC_DATA11__UART6_DTE_RTS | MUX_PAD_CTRL(UART_PAD_CTRL), | |
195 | +}; | |
196 | + | |
197 | +/* SER1/UART2 */ | |
198 | +static iomux_v3_cfg_t const uart2_pads[] = { | |
199 | + MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
200 | + MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
201 | +}; | |
202 | + | |
203 | +/* SER2/UART7 */ | |
204 | +static iomux_v3_cfg_t const uart7_pads[] = { | |
205 | + MX7D_PAD_EPDC_DATA13__UART7_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
206 | + MX7D_PAD_EPDC_DATA12__UART7_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
207 | + MX7D_PAD_EPDC_DATA14__UART7_DTE_CTS | MUX_PAD_CTRL(UART_PAD_CTRL), | |
208 | + MX7D_PAD_EPDC_DATA15__UART7_DTE_RTS | MUX_PAD_CTRL(UART_PAD_CTRL), | |
209 | +}; | |
210 | + | |
211 | +/* SER3/UART3 Debug Port */ | |
212 | +static iomux_v3_cfg_t const uart3_pads[] = { | |
213 | + MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
214 | + MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
215 | +}; | |
216 | + | |
217 | +/* RESET_OUT# */ | |
218 | +static iomux_v3_cfg_t const reset_out_pads[] = { | |
219 | + MX7D_PAD_EPDC_BDR1__GPIO2_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL), | |
220 | +}; | |
221 | + | |
222 | +/* SD Card */ | |
223 | +static iomux_v3_cfg_t const usdhc1_pads[] = { | |
224 | + MX7D_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
225 | + MX7D_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
226 | + MX7D_PAD_SD1_DATA0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
227 | + MX7D_PAD_SD1_DATA1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
228 | + MX7D_PAD_SD1_DATA2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
229 | + MX7D_PAD_SD1_DATA3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
230 | + | |
231 | + MX7D_PAD_SD1_CD_B__GPIO5_IO0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /*CD */ | |
232 | + MX7D_PAD_SD1_WP__GPIO5_IO1 | MUX_PAD_CTRL(NO_PAD_CTRL), /* WP */ | |
233 | + MX7D_PAD_SD1_RESET_B__GPIO5_IO2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* SDIO_PWR_EN */ | |
234 | +}; | |
235 | + | |
236 | +/* eMMC */ | |
237 | +static iomux_v3_cfg_t const usdhc3_emmc_pads[] = { | |
238 | + MX7D_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
239 | + MX7D_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
240 | + MX7D_PAD_SD3_DATA0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
241 | + MX7D_PAD_SD3_DATA1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
242 | + MX7D_PAD_SD3_DATA2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
243 | + MX7D_PAD_SD3_DATA3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
244 | + MX7D_PAD_SD3_DATA4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
245 | + MX7D_PAD_SD3_DATA5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
246 | + MX7D_PAD_SD3_DATA6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
247 | + MX7D_PAD_SD3_DATA7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
248 | + MX7D_PAD_SD3_STROBE__SD3_STROBE | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
249 | + MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(USDHC_PAD_CTRL), | |
250 | +}; | |
251 | + | |
252 | +/* SPI0 */ | |
253 | +static iomux_v3_cfg_t const ecspi1_pads[] = { | |
254 | + MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
255 | + MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
256 | + MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
257 | + MX7D_PAD_ECSPI1_SS0__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL), /*SS0#*/ | |
258 | + MX7D_PAD_UART1_RX_DATA__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL), /*SS1#*/ | |
259 | +}; | |
260 | + | |
261 | +/* ESPI */ | |
262 | +static iomux_v3_cfg_t const ecspi3_pads[] = { | |
263 | + MX7D_PAD_SAI2_RX_DATA__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
264 | + MX7D_PAD_SAI2_TX_BCLK__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
265 | + MX7D_PAD_SAI2_TX_SYNC__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
266 | + MX7D_PAD_SAI2_TX_DATA__ECSPI3_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL), /*SS0#*/ | |
267 | + MX7D_PAD_SD2_CD_B__ECSPI3_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL), /*SS2#*/ | |
268 | +}; | |
269 | + | |
270 | +/* CAN0/FLEXCAN1 */ | |
271 | +static iomux_v3_cfg_t const flexcan1_pads[] = { | |
272 | + MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX | MUX_PAD_CTRL(WEAK_PULLUP), | |
273 | + MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX | MUX_PAD_CTRL(WEAK_PULLUP), | |
274 | +}; | |
275 | + | |
276 | +/* CAN1/FLEXCAN2 */ | |
277 | +static iomux_v3_cfg_t const flexcan2_pads[] = { | |
278 | + MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX | MUX_PAD_CTRL(WEAK_PULLUP), | |
279 | + MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX | MUX_PAD_CTRL(WEAK_PULLUP), | |
280 | +}; | |
281 | + | |
282 | +/* GPIOs */ | |
283 | +static iomux_v3_cfg_t const gpios_pads[] = { | |
284 | + MX7D_PAD_EPDC_DATA00__GPIO2_IO0 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO0 */ | |
285 | + MX7D_PAD_EPDC_DATA01__GPIO2_IO1 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO1 */ | |
286 | + MX7D_PAD_EPDC_DATA02__GPIO2_IO2 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO2 */ | |
287 | + MX7D_PAD_EPDC_DATA03__GPIO2_IO3 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO3 */ | |
288 | + MX7D_PAD_EPDC_DATA04__GPIO2_IO4 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO4 */ | |
289 | + MX7D_PAD_EPDC_DATA05__GPIO2_IO5 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO6 */ | |
290 | + MX7D_PAD_EPDC_DATA07__GPIO2_IO7 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO7 */ | |
291 | + MX7D_PAD_EPDC_DATA06__GPIO2_IO6 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO8 */ | |
292 | + MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO9 */ | |
293 | + MX7D_PAD_UART3_RTS_B__GPIO4_IO6 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO10 */ | |
294 | + MX7D_PAD_UART3_CTS_B__GPIO4_IO7 | MUX_PAD_CTRL(WEAK_PULLUP), /* GPIO11 */ | |
295 | +}; | |
296 | + | |
297 | +/* LVDS channel selection, set low as single channel LVDS and high as dual channel LVDS */ | |
298 | +static iomux_v3_cfg_t const lvds_ch_sel_pads[] = { | |
299 | + MX7D_PAD_SD2_CMD__GPIO5_IO13 | MUX_PAD_CTRL(WEAK_PULLUP), /* LVDS_CH_SEL */ | |
300 | +}; | |
301 | + | |
302 | +/* Misc. pins */ | |
303 | +static iomux_v3_cfg_t const misc_pads[] = { | |
304 | + MX7D_PAD_SD2_DATA0__GPIO5_IO14 | MUX_PAD_CTRL(WEAK_PULLUP), /* SLEEP# */ | |
305 | + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(WEAK_PULLUP), /* CHARGER_PRSNT# */ | |
306 | + MX7D_PAD_GPIO1_IO08__GPIO1_IO8 | MUX_PAD_CTRL(WEAK_PULLUP), /* CHARGING# */ | |
307 | + MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 | MUX_PAD_CTRL(WEAK_PULLUP), /* CARRIER_STBY# */ | |
308 | + MX7D_PAD_SAI1_RX_BCLK__GPIO6_IO17 | MUX_PAD_CTRL(WEAK_PULLUP), /* CARRIER_PWR_ON# */ | |
309 | + MX7D_PAD_SD2_RESET_B__GPIO5_IO11 | MUX_PAD_CTRL(WEAK_PULLUP), /* BATLOW# */ | |
310 | + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), /* PCIe_RST# */ | |
311 | +}; | |
312 | + | |
313 | +#ifdef CONFIG_VIDEO_MXS | |
314 | +static iomux_v3_cfg_t const lcd_pads[] = { | |
315 | + MX7D_PAD_LCD_CLK__LCD_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
316 | + MX7D_PAD_LCD_ENABLE__LCD_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
317 | + MX7D_PAD_LCD_HSYNC__LCD_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
318 | + MX7D_PAD_LCD_VSYNC__LCD_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
319 | + MX7D_PAD_LCD_DATA00__LCD_DATA0 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
320 | + MX7D_PAD_LCD_DATA01__LCD_DATA1 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
321 | + MX7D_PAD_LCD_DATA02__LCD_DATA2 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
322 | + MX7D_PAD_LCD_DATA03__LCD_DATA3 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
323 | + MX7D_PAD_LCD_DATA04__LCD_DATA4 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
324 | + MX7D_PAD_LCD_DATA05__LCD_DATA5 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
325 | + MX7D_PAD_LCD_DATA06__LCD_DATA6 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
326 | + MX7D_PAD_LCD_DATA07__LCD_DATA7 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
327 | + MX7D_PAD_LCD_DATA08__LCD_DATA8 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
328 | + MX7D_PAD_LCD_DATA09__LCD_DATA9 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
329 | + MX7D_PAD_LCD_DATA10__LCD_DATA10 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
330 | + MX7D_PAD_LCD_DATA11__LCD_DATA11 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
331 | + MX7D_PAD_LCD_DATA12__LCD_DATA12 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
332 | + MX7D_PAD_LCD_DATA13__LCD_DATA13 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
333 | + MX7D_PAD_LCD_DATA14__LCD_DATA14 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
334 | + MX7D_PAD_LCD_DATA15__LCD_DATA15 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
335 | + MX7D_PAD_LCD_DATA16__LCD_DATA16 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
336 | + MX7D_PAD_LCD_DATA17__LCD_DATA17 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
337 | + MX7D_PAD_LCD_DATA18__LCD_DATA18 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
338 | + MX7D_PAD_LCD_DATA19__LCD_DATA19 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
339 | + MX7D_PAD_LCD_DATA20__LCD_DATA20 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
340 | + MX7D_PAD_LCD_DATA21__LCD_DATA21 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
341 | + MX7D_PAD_LCD_DATA22__LCD_DATA22 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
342 | + MX7D_PAD_LCD_DATA23__LCD_DATA23 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
343 | + | |
344 | + MX7D_PAD_LCD_RESET__GPIO3_IO4 | MUX_PAD_CTRL(LCD_PAD_CTRL), | |
345 | +}; | |
346 | + | |
347 | +static iomux_v3_cfg_t const backlight_pads[] = { | |
348 | + /* Backlight Enable for RGB: S127 */ | |
349 | + MX7D_PAD_GPIO1_IO02__GPIO1_IO2 | MUX_PAD_CTRL(WEAK_PULLUP), | |
350 | + | |
351 | + /* PWM Backlight Control: S141. Use GPIO for Brightness adjustment, duty cycle = period */ | |
352 | + MX7D_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(NO_PAD_CTRL), | |
353 | +}; | |
354 | + | |
355 | +void do_enable_parallel_lcd(struct display_info_t const *dev) | |
356 | +{ | |
357 | + imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads)); | |
358 | + | |
359 | + imx_iomux_v3_setup_multiple_pads(backlight_pads, ARRAY_SIZE(backlight_pads)); | |
360 | + | |
361 | + /* Reset LCD */ | |
362 | + /*gpio_direction_output(IMX_GPIO_NR(3, 4) , 0); | |
363 | + udelay(500);*/ | |
364 | + gpio_direction_output(IMX_GPIO_NR(3, 4) , 1); | |
365 | + | |
366 | + /* Turn on Backlight */ | |
367 | + gpio_direction_output(IMX_GPIO_NR(1, 2), 1); | |
368 | + | |
369 | + /* Set Brightness to high */ | |
370 | + gpio_direction_output(IMX_GPIO_NR(1, 0) , 1); | |
371 | +} | |
372 | + | |
373 | + | |
374 | +/* LVDS Panel for AUO G070VW01 V0 7-inch Color TFT 800x480 Panel Settings */ | |
375 | +struct display_info_t const displays[] = {{ | |
376 | + .bus = ELCDIF1_IPS_BASE_ADDR, | |
377 | + .addr = 0, | |
378 | + .pixfmt = 24, | |
379 | + .detect = NULL, | |
380 | + .enable = do_enable_parallel_lcd, | |
381 | + .mode = { | |
382 | + .name = "G070VW01", | |
383 | + .xres = 800, | |
384 | + .yres = 480, | |
385 | + .pixclock = 31069, | |
386 | + .left_margin = 64, | |
387 | + .right_margin = 64, | |
388 | + .upper_margin = 12, | |
389 | + .lower_margin = 4, | |
390 | + .hsync_len = 128, | |
391 | + .vsync_len = 12, | |
392 | + .sync = 0, | |
393 | + .vmode = FB_VMODE_NONINTERLACED | |
394 | +} } }; | |
395 | +size_t display_count = ARRAY_SIZE(displays); | |
396 | +#endif | |
397 | + | |
398 | +static void setup_iomux_uart6(void) | |
399 | +{ | |
400 | + imx_iomux_v3_setup_multiple_pads(uart6_pads, ARRAY_SIZE(uart6_pads)); | |
401 | +} | |
402 | + | |
403 | +static void setup_iomux_uart2(void) | |
404 | +{ | |
405 | + imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads)); | |
406 | +} | |
407 | + | |
408 | +static void setup_iomux_uart7(void) | |
409 | +{ | |
410 | + imx_iomux_v3_setup_multiple_pads(uart7_pads, ARRAY_SIZE(uart7_pads)); | |
411 | +} | |
412 | + | |
413 | +static void setup_iomux_uart3(void) | |
414 | +{ | |
415 | + imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads)); | |
416 | +} | |
417 | + | |
418 | +static void setup_iomux_reset_out(void) | |
419 | +{ | |
420 | + imx_iomux_v3_setup_multiple_pads(reset_out_pads, ARRAY_SIZE(reset_out_pads)); | |
421 | + | |
422 | + /* Set CPU RESET_OUT as Output */ | |
423 | + gpio_direction_output(IMX_GPIO_NR(2, 29) , 0); | |
424 | +} | |
425 | + | |
426 | +static void setup_iomux_spi1(void) | |
427 | +{ | |
428 | + imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); | |
429 | + gpio_direction_output(IMX_GPIO_NR(4, 19), 0); | |
430 | + gpio_direction_output(IMX_GPIO_NR(4, 0), 0); | |
431 | +} | |
432 | + | |
433 | +static void setup_iomux_spi3(void) | |
434 | +{ | |
435 | + imx_iomux_v3_setup_multiple_pads(ecspi3_pads, ARRAY_SIZE(ecspi3_pads)); | |
436 | + gpio_direction_output(IMX_GPIO_NR(6, 22), 0); | |
437 | + gpio_direction_output(IMX_GPIO_NR(5, 9), 0); | |
438 | +} | |
439 | + | |
440 | +static void setup_iomux_gpios(void) | |
441 | +{ | |
442 | + imx_iomux_v3_setup_multiple_pads(gpios_pads, ARRAY_SIZE(gpios_pads)); | |
443 | + gpio_direction_output(IMX_GPIO_NR(2, 0), 0); | |
444 | + gpio_direction_output(IMX_GPIO_NR(2, 1), 0); | |
445 | + gpio_direction_output(IMX_GPIO_NR(2, 2), 0); | |
446 | + gpio_direction_output(IMX_GPIO_NR(2, 3), 0); | |
447 | + gpio_direction_output(IMX_GPIO_NR(2, 4), 0); | |
448 | + gpio_direction_input(IMX_GPIO_NR(2, 5)); | |
449 | + gpio_direction_input(IMX_GPIO_NR(2, 7)); | |
450 | + gpio_direction_input(IMX_GPIO_NR(2, 6)); | |
451 | + gpio_direction_input(IMX_GPIO_NR(4, 1)); | |
452 | + gpio_direction_input(IMX_GPIO_NR(4, 6)); | |
453 | + gpio_direction_input(IMX_GPIO_NR(4, 7)); | |
454 | +} | |
455 | + | |
456 | +static void setup_iomux_lvds_ch_sel(void) | |
457 | +{ | |
458 | + imx_iomux_v3_setup_multiple_pads(lvds_ch_sel_pads, ARRAY_SIZE(lvds_ch_sel_pads)); | |
459 | + gpio_direction_output(IMX_GPIO_NR(5, 13), 0); | |
460 | +} | |
461 | + | |
462 | +static void setup_iomux_misc(void) | |
463 | +{ | |
464 | + imx_iomux_v3_setup_multiple_pads(misc_pads, ARRAY_SIZE(misc_pads)); | |
465 | + gpio_direction_input(IMX_GPIO_NR(5, 14)); | |
466 | + gpio_direction_input(IMX_GPIO_NR(1, 8)); | |
467 | + gpio_direction_input(IMX_GPIO_NR(1, 9)); | |
468 | + gpio_direction_input(IMX_GPIO_NR(5, 11)); | |
469 | + gpio_direction_output(IMX_GPIO_NR(6, 16), 0); | |
470 | + gpio_direction_output(IMX_GPIO_NR(6, 17), 0); | |
471 | + gpio_direction_output(IMX_GPIO_NR(2, 28), 0); | |
472 | +} | |
473 | + | |
474 | +static void setup_iomux_flexcan1(void) | |
475 | +{ | |
476 | + imx_iomux_v3_setup_multiple_pads(flexcan1_pads, ARRAY_SIZE(flexcan1_pads)); | |
477 | +} | |
478 | + | |
479 | +static void setup_iomux_flexcan2(void) | |
480 | +{ | |
481 | + imx_iomux_v3_setup_multiple_pads(flexcan2_pads, ARRAY_SIZE(flexcan2_pads)); | |
482 | +} | |
483 | + | |
484 | +#ifdef CONFIG_FSL_ESDHC | |
485 | + | |
486 | +#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 0) | |
487 | +#define USDHC1_PWR_GPIO IMX_GPIO_NR(5, 2) | |
488 | +#define USDHC3_PWR_GPIO IMX_GPIO_NR(6, 11) | |
489 | + | |
490 | +static struct fsl_esdhc_cfg usdhc_cfg[3] = { | |
491 | + {USDHC1_BASE_ADDR, 0, 4}, | |
492 | + {USDHC3_BASE_ADDR}, | |
493 | +}; | |
494 | + | |
495 | +int board_mmc_get_env_dev(int devno) | |
496 | +{ | |
497 | + if (devno == 2) | |
498 | + devno--; | |
499 | + | |
500 | + return devno; | |
501 | +} | |
502 | + | |
503 | +int mmc_map_to_kernel_blk(int dev_no) | |
504 | +{ | |
505 | + if (dev_no == 1) | |
506 | + dev_no++; | |
507 | + | |
508 | + return dev_no; | |
509 | +} | |
510 | + | |
511 | +int board_mmc_getcd(struct mmc *mmc) | |
512 | +{ | |
513 | + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; | |
514 | + int ret = 0; | |
515 | + | |
516 | + switch (cfg->esdhc_base) { | |
517 | + case USDHC1_BASE_ADDR: | |
518 | + ret = !gpio_get_value(USDHC1_CD_GPIO); | |
519 | + break; | |
520 | + case USDHC3_BASE_ADDR: | |
521 | + ret = 1; /* Assume uSDHC3 emmc is always present */ | |
522 | + break; | |
523 | + } | |
524 | + | |
525 | + return ret; | |
526 | +} | |
527 | + | |
528 | +int board_mmc_init(bd_t *bis) | |
529 | +{ | |
530 | + int i, ret; | |
531 | + /* | |
532 | + * According to the board_mmc_init() the following map is done: | |
533 | + * (U-Boot device node) (Physical Port) | |
534 | + * mmc0 USDHC1 | |
535 | + * mmc2 USDHC3 (eMMC) | |
536 | + */ | |
537 | + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { | |
538 | + switch (i) { | |
539 | + case 0: | |
540 | + imx_iomux_v3_setup_multiple_pads( | |
541 | + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); | |
542 | + gpio_request(USDHC1_CD_GPIO, "usdhc1_cd"); | |
543 | + gpio_direction_input(USDHC1_CD_GPIO); | |
544 | + gpio_request(USDHC1_PWR_GPIO, "usdhc1_pwr"); | |
545 | + gpio_direction_output(USDHC1_PWR_GPIO, 0); | |
546 | + udelay(500); | |
547 | + gpio_direction_output(USDHC1_PWR_GPIO, 1); | |
548 | + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); | |
549 | + break; | |
550 | + case 1: | |
551 | + imx_iomux_v3_setup_multiple_pads( | |
552 | + usdhc3_emmc_pads, ARRAY_SIZE(usdhc3_emmc_pads)); | |
553 | + gpio_request(USDHC3_PWR_GPIO, "usdhc3_pwr"); | |
554 | + gpio_direction_output(USDHC3_PWR_GPIO, 0); | |
555 | + udelay(500); | |
556 | + gpio_direction_output(USDHC3_PWR_GPIO, 1); | |
557 | + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); | |
558 | + break; | |
559 | + default: | |
560 | + printf("Warning: you configured more USDHC controllers" | |
561 | + "(%d) than supported by the board\n", i + 1); | |
562 | + return -EINVAL; | |
563 | + } | |
564 | + | |
565 | + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); | |
566 | + if (ret) | |
567 | + return ret; | |
568 | + } | |
569 | + | |
570 | + return 0; | |
571 | +} | |
572 | +#endif | |
573 | + | |
574 | +#ifdef CONFIG_FEC_MXC | |
575 | +static iomux_v3_cfg_t const fec1_pads[] = { | |
576 | + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
577 | + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
578 | + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
579 | + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
580 | + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
581 | + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
582 | + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
583 | + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
584 | + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
585 | + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
586 | + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
587 | + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
588 | + MX7D_PAD_GPIO1_IO10__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), | |
589 | + MX7D_PAD_GPIO1_IO11__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), | |
590 | +}; | |
591 | + | |
592 | +static iomux_v3_cfg_t const fec2_pads[] = { | |
593 | + MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
594 | + MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
595 | + MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
596 | + MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
597 | + MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
598 | + MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL), | |
599 | + MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
600 | + MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
601 | + MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
602 | + MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
603 | + MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
604 | + MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), | |
605 | + MX7D_PAD_GPIO1_IO10__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), | |
606 | + MX7D_PAD_GPIO1_IO11__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII), | |
607 | +}; | |
608 | + | |
609 | +static void setup_iomux_fec(void) | |
610 | +{ | |
611 | + if (0 == CONFIG_FEC_ENET_DEV) { | |
612 | + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); | |
613 | + gpio_direction_input(IMX_GPIO_NR(7, 15)); | |
614 | + } else { | |
615 | + imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads)); | |
616 | + gpio_direction_input(IMX_GPIO_NR(7, 14)); | |
617 | + } | |
618 | +} | |
619 | + | |
620 | +int board_eth_init(bd_t *bis) | |
621 | +{ | |
622 | +#if defined(CONFIG_MAC_ADDR_IN_EEPROM) | |
623 | + | |
624 | + uchar env_enetaddr[6]; | |
625 | + int enetaddr_found; | |
626 | + | |
627 | + enetaddr_found = eth_getenv_enetaddr("ethaddr", env_enetaddr); | |
628 | + | |
629 | + uint8_t enetaddr[8]; | |
630 | + int eeprom_mac_read; | |
631 | + | |
632 | + /* Read Ethernet MAC address from EEPROM */ | |
633 | + eeprom_mac_read = smarcfimx7_read_mac_address(enetaddr); | |
634 | + | |
635 | + /* | |
636 | + * MAC address not present in the environment | |
637 | + * try and read the MAC address from EEPROM flash | |
638 | + * and set it. | |
639 | + */ | |
640 | + if (!enetaddr_found) { | |
641 | + if (eeprom_mac_read) | |
642 | + /* Set Ethernet MAC address from EEPROM */ | |
643 | + smarcfimx7_sync_env_enetaddr(enetaddr); | |
644 | + } else { | |
645 | + /* | |
646 | + * MAC address present in environment compare it with | |
647 | + * the MAC address in EEPROM and warn on mismatch | |
648 | + */ | |
649 | + if (eeprom_mac_read && memcmp(enetaddr, env_enetaddr, 6)) | |
650 | + printf("Warning: MAC address in EEPROM don't match " | |
651 | + "with the MAC address in the environment\n"); | |
652 | + printf("Default using MAC address from environment\n"); | |
653 | + } | |
654 | + | |
655 | + uchar env_enet1addr[6]; | |
656 | + int enet1addr_found; | |
657 | + | |
658 | + enet1addr_found = eth_getenv_enetaddr("eth1addr", env_enet1addr); | |
659 | + | |
660 | + uint8_t enet1addr[8]; | |
661 | + int eeprom_mac1_read; | |
662 | + | |
663 | + /* Read Ethernet MAC address from EEPROM */ | |
664 | + eeprom_mac1_read = smarcfimx7_read_mac_address(enet1addr); | |
665 | + | |
666 | + /* | |
667 | + * MAC address not present in the environment | |
668 | + * try and read the MAC address from EEPROM flash | |
669 | + * and set it. | |
670 | + */ | |
671 | + if (!enet1addr_found) { | |
672 | + if (eeprom_mac1_read) | |
673 | + /* Set Ethernet MAC address from EEPROM */ | |
674 | + smarcfimx7_sync_env_enet1addr(enet1addr); | |
675 | + } else { | |
676 | + /* | |
677 | + * MAC address present in environment compare it with | |
678 | + * the MAC address in EEPROM and warn on mismatch | |
679 | + */ | |
680 | + if (eeprom_mac_read && memcmp(enet1addr, env_enet1addr, 6)) | |
681 | + printf("Warning: 2nd GBE MAC address in EEPROM don't match " | |
682 | + "with the MAC address in the environment\n"); | |
683 | + printf("Default using 2nd GBE MAC address from environment\n"); | |
684 | + } | |
685 | + | |
686 | +#endif | |
687 | + | |
688 | + int ret; | |
689 | + | |
690 | + setup_iomux_fec(); | |
691 | + | |
692 | + ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | |
693 | + CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | |
694 | + if (ret) | |
695 | + printf("FEC1 MXC: %s:failed\n", __func__); | |
696 | + | |
697 | + return ret; | |
698 | +} | |
699 | + | |
700 | +static int setup_fec(int fec_id) | |
701 | +{ | |
702 | + struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs | |
703 | + = (struct iomuxc_gpr_base_regs *) IOMUXC_GPR_BASE_ADDR; | |
704 | + | |
705 | + if (0 == fec_id) { | |
706 | + /* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17]*/ | |
707 | + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], | |
708 | + (IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK | | |
709 | + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0); | |
710 | + } else { | |
711 | + /* Use 125M anatop REF_CLK2 for ENET2, clear gpr1[14], gpr1[18]*/ | |
712 | + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], | |
713 | + (IOMUXC_GPR_GPR1_GPR_ENET2_TX_CLK_SEL_MASK | | |
714 | + IOMUXC_GPR_GPR1_GPR_ENET2_CLK_DIR_MASK), 0); | |
715 | + } | |
716 | + | |
717 | + return set_clk_enet(ENET_125MHz); | |
718 | + | |
719 | +} | |
720 | + | |
721 | +int board_phy_config(struct phy_device *phydev) | |
722 | +{ | |
723 | + /* enable rgmii rxc skew and phy mode select to RGMII copper */ | |
724 | + /*phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x21); | |
725 | + phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x7ea8); | |
726 | + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x2f); | |
727 | + phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x71b7);*/ | |
728 | + | |
729 | + if (phydev->drv->config) | |
730 | + phydev->drv->config(phydev); | |
731 | + return 0; | |
732 | +} | |
733 | +#endif | |
734 | + | |
735 | +#ifdef CONFIG_MXC_SPI | |
736 | +/* SPI2 (SPINOR) */ | |
737 | +static iomux_v3_cfg_t const ecspi2_pads[] = { | |
738 | + MX7D_PAD_ECSPI2_SCLK__ECSPI2_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
739 | + MX7D_PAD_ECSPI2_MOSI__ECSPI2_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
740 | + MX7D_PAD_ECSPI2_MISO__ECSPI2_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), | |
741 | + MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL), /*SS0#*/ | |
742 | +}; | |
743 | + | |
744 | +static void setup_spinor(void) | |
745 | +{ | |
746 | + imx_iomux_v3_setup_multiple_pads(ecspi2_pads, ARRAY_SIZE(ecspi2_pads)); | |
747 | + gpio_direction_output(IMX_GPIO_NR(4, 23), 0); | |
748 | +} | |
749 | + | |
750 | +int board_spi_cs_gpio(unsigned bus, unsigned cs) | |
751 | +{ | |
752 | + return (bus == 1 && cs == 0) ? (IMX_GPIO_NR(4, 23)) : -1; | |
753 | +} | |
754 | +#endif | |
755 | + | |
756 | +#ifdef CONFIG_MXC_EPDC | |
757 | +static iomux_v3_cfg_t const epdc_enable_pads[] = { | |
758 | + MX7D_PAD_EPDC_DATA00__EPDC_DATA0 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
759 | + MX7D_PAD_EPDC_DATA01__EPDC_DATA1 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
760 | + MX7D_PAD_EPDC_DATA02__EPDC_DATA2 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
761 | + MX7D_PAD_EPDC_DATA03__EPDC_DATA3 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
762 | + MX7D_PAD_EPDC_DATA04__EPDC_DATA4 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
763 | + MX7D_PAD_EPDC_DATA05__EPDC_DATA5 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
764 | + MX7D_PAD_EPDC_DATA06__EPDC_DATA6 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
765 | + MX7D_PAD_EPDC_DATA07__EPDC_DATA7 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
766 | + MX7D_PAD_EPDC_SDCLK__EPDC_SDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
767 | + MX7D_PAD_EPDC_SDLE__EPDC_SDLE | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
768 | + MX7D_PAD_EPDC_SDOE__EPDC_SDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
769 | + MX7D_PAD_EPDC_SDSHR__EPDC_SDSHR | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
770 | + MX7D_PAD_EPDC_SDCE0__EPDC_SDCE0 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
771 | + MX7D_PAD_EPDC_SDCE1__EPDC_SDCE1 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
772 | + MX7D_PAD_EPDC_GDCLK__EPDC_GDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
773 | + MX7D_PAD_EPDC_GDOE__EPDC_GDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
774 | + MX7D_PAD_EPDC_GDRL__EPDC_GDRL | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
775 | + MX7D_PAD_EPDC_GDSP__EPDC_GDSP | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
776 | + MX7D_PAD_EPDC_BDR0__EPDC_BDR0 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
777 | + MX7D_PAD_EPDC_BDR1__EPDC_BDR1 | MUX_PAD_CTRL(EPDC_PAD_CTRL), | |
778 | +}; | |
779 | + | |
780 | +static iomux_v3_cfg_t const epdc_disable_pads[] = { | |
781 | + MX7D_PAD_EPDC_DATA00__GPIO2_IO0, | |
782 | + MX7D_PAD_EPDC_DATA01__GPIO2_IO1, | |
783 | + MX7D_PAD_EPDC_DATA02__GPIO2_IO2, | |
784 | + MX7D_PAD_EPDC_DATA03__GPIO2_IO3, | |
785 | + MX7D_PAD_EPDC_DATA04__GPIO2_IO4, | |
786 | + MX7D_PAD_EPDC_DATA05__GPIO2_IO5, | |
787 | + MX7D_PAD_EPDC_DATA06__GPIO2_IO6, | |
788 | + MX7D_PAD_EPDC_DATA07__GPIO2_IO7, | |
789 | + MX7D_PAD_EPDC_SDCLK__GPIO2_IO16, | |
790 | + MX7D_PAD_EPDC_SDLE__GPIO2_IO17, | |
791 | + MX7D_PAD_EPDC_SDOE__GPIO2_IO18, | |
792 | + MX7D_PAD_EPDC_SDSHR__GPIO2_IO19, | |
793 | + MX7D_PAD_EPDC_SDCE0__GPIO2_IO20, | |
794 | + MX7D_PAD_EPDC_SDCE1__GPIO2_IO21, | |
795 | + MX7D_PAD_EPDC_GDCLK__GPIO2_IO24, | |
796 | + MX7D_PAD_EPDC_GDOE__GPIO2_IO25, | |
797 | + MX7D_PAD_EPDC_GDRL__GPIO2_IO26, | |
798 | + MX7D_PAD_EPDC_GDSP__GPIO2_IO27, | |
799 | + MX7D_PAD_EPDC_BDR0__GPIO2_IO28, | |
800 | + MX7D_PAD_EPDC_BDR1__GPIO2_IO29, | |
801 | +}; | |
802 | + | |
803 | +vidinfo_t panel_info = { | |
804 | + .vl_refresh = 85, | |
805 | + .vl_col = 1024, | |
806 | + .vl_row = 758, | |
807 | + .vl_pixclock = 40000000, | |
808 | + .vl_left_margin = 12, | |
809 | + .vl_right_margin = 76, | |
810 | + .vl_upper_margin = 4, | |
811 | + .vl_lower_margin = 5, | |
812 | + .vl_hsync = 12, | |
813 | + .vl_vsync = 2, | |
814 | + .vl_sync = 0, | |
815 | + .vl_mode = 0, | |
816 | + .vl_flag = 0, | |
817 | + .vl_bpix = 3, | |
818 | + .cmap = 0, | |
819 | +}; | |
820 | + | |
821 | +struct epdc_timing_params panel_timings = { | |
822 | + .vscan_holdoff = 4, | |
823 | + .sdoed_width = 10, | |
824 | + .sdoed_delay = 20, | |
825 | + .sdoez_width = 10, | |
826 | + .sdoez_delay = 20, | |
827 | + .gdclk_hp_offs = 524, | |
828 | + .gdsp_offs = 327, | |
829 | + .gdoe_offs = 0, | |
830 | + .gdclk_offs = 19, | |
831 | + .num_ce = 1, | |
832 | +}; | |
833 | + | |
834 | +static void setup_epdc_power(void) | |
835 | +{ | |
836 | + /* IOMUX_GPR1: bit30: Disable On-chip RAM EPDC Function */ | |
837 | + struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs | |
838 | + = (struct iomuxc_gpr_base_regs *) IOMUXC_GPR_BASE_ADDR; | |
839 | + | |
840 | + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], | |
841 | + IOMUXC_GPR_GPR1_GPR_ENABLE_OCRAM_EPDC_MASK, 0); | |
842 | + | |
843 | + /* Setup epdc voltage */ | |
844 | + | |
845 | + /* EPDC_PWRSTAT - GPIO2[31] for PWR_GOOD status */ | |
846 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 | | |
847 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
848 | + gpio_direction_input(IMX_GPIO_NR(2, 31)); | |
849 | + | |
850 | + /* EPDC_VCOM0 - GPIO4[14] for VCOM control */ | |
851 | + imx_iomux_v3_setup_pad(MX7D_PAD_I2C4_SCL__GPIO4_IO14 | | |
852 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
853 | + | |
854 | + /* Set as output */ | |
855 | + gpio_direction_output(IMX_GPIO_NR(4, 14), 1); | |
856 | + | |
857 | + /* EPDC_PWRWAKEUP - GPIO2[23] for EPD PMIC WAKEUP */ | |
858 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_SDCE3__GPIO2_IO23 | | |
859 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
860 | + /* Set as output */ | |
861 | + gpio_direction_output(IMX_GPIO_NR(2, 23), 1); | |
862 | + | |
863 | + /* EPDC_PWRCTRL0 - GPIO2[30] for EPD PWR CTL0 */ | |
864 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 | | |
865 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
866 | + /* Set as output */ | |
867 | + gpio_direction_output(IMX_GPIO_NR(2, 30), 1); | |
868 | +} | |
869 | + | |
870 | +static void epdc_enable_pins(void) | |
871 | +{ | |
872 | + /* epdc iomux settings */ | |
873 | + imx_iomux_v3_setup_multiple_pads(epdc_enable_pads, | |
874 | + ARRAY_SIZE(epdc_enable_pads)); | |
875 | +} | |
876 | + | |
877 | +static void epdc_disable_pins(void) | |
878 | +{ | |
879 | + /* Configure MUX settings for EPDC pins to GPIO and drive to 0 */ | |
880 | + imx_iomux_v3_setup_multiple_pads(epdc_disable_pads, | |
881 | + ARRAY_SIZE(epdc_disable_pads)); | |
882 | +} | |
883 | + | |
884 | +static void setup_epdc(void) | |
885 | +{ | |
886 | + /*** epdc Maxim PMIC settings ***/ | |
887 | + | |
888 | + /* EPDC_PWRSTAT - GPIO2[31] for PWR_GOOD status */ | |
889 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 | | |
890 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
891 | + | |
892 | + /* EPDC_VCOM0 - GPIO4[14] for VCOM control */ | |
893 | + imx_iomux_v3_setup_pad(MX7D_PAD_I2C4_SCL__GPIO4_IO14 | | |
894 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
895 | + | |
896 | + /* EPDC_PWRWAKEUP - GPIO4[23] for EPD PMIC WAKEUP */ | |
897 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_SDCE3__GPIO2_IO23 | | |
898 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
899 | + | |
900 | + /* EPDC_PWRCTRL0 - GPIO4[20] for EPD PWR CTL0 */ | |
901 | + imx_iomux_v3_setup_pad(MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 | | |
902 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); | |
903 | + | |
904 | + /* Set pixel clock rates for EPDC in clock.c */ | |
905 | + | |
906 | + panel_info.epdc_data.wv_modes.mode_init = 0; | |
907 | + panel_info.epdc_data.wv_modes.mode_du = 1; | |
908 | + panel_info.epdc_data.wv_modes.mode_gc4 = 3; | |
909 | + panel_info.epdc_data.wv_modes.mode_gc8 = 2; | |
910 | + panel_info.epdc_data.wv_modes.mode_gc16 = 2; | |
911 | + panel_info.epdc_data.wv_modes.mode_gc32 = 2; | |
912 | + | |
913 | + panel_info.epdc_data.epdc_timings = panel_timings; | |
914 | + | |
915 | + setup_epdc_power(); | |
916 | +} | |
917 | + | |
918 | +void epdc_power_on(void) | |
919 | +{ | |
920 | + unsigned int reg; | |
921 | + struct gpio_regs *gpio_regs = (struct gpio_regs *)GPIO2_BASE_ADDR; | |
922 | + | |
923 | + /* Set EPD_PWR_CTL0 to high - enable EINK_VDD (3.15) */ | |
924 | + gpio_set_value(IMX_GPIO_NR(2, 30), 1); | |
925 | + udelay(1000); | |
926 | + | |
927 | + /* Enable epdc signal pin */ | |
928 | + epdc_enable_pins(); | |
929 | + | |
930 | + /* Set PMIC Wakeup to high - enable Display power */ | |
931 | + gpio_set_value(IMX_GPIO_NR(2, 23), 1); | |
932 | + | |
933 | + /* Wait for PWRGOOD == 1 */ | |
934 | + while (1) { | |
935 | + reg = readl(&gpio_regs->gpio_psr); | |
936 | + if (!(reg & (1 << 31))) | |
937 | + break; | |
938 | + | |
939 | + udelay(100); | |
940 | + } | |
941 | + | |
942 | + /* Enable VCOM */ | |
943 | + gpio_set_value(IMX_GPIO_NR(4, 14), 1); | |
944 | + | |
945 | + udelay(500); | |
946 | +} | |
947 | + | |
948 | +void epdc_power_off(void) | |
949 | +{ | |
950 | + /* Set PMIC Wakeup to low - disable Display power */ | |
951 | + gpio_set_value(IMX_GPIO_NR(2, 23), 0); | |
952 | + | |
953 | + /* Disable VCOM */ | |
954 | + gpio_set_value(IMX_GPIO_NR(4, 14), 0); | |
955 | + | |
956 | + epdc_disable_pins(); | |
957 | + | |
958 | + /* Set EPD_PWR_CTL0 to low - disable EINK_VDD (3.15) */ | |
959 | + gpio_set_value(IMX_GPIO_NR(2, 30), 0); | |
960 | +} | |
961 | +#endif | |
962 | + | |
963 | +#ifdef CONFIG_USB_EHCI_MX7 | |
964 | +static iomux_v3_cfg_t const usb_otg1_pads[] = { | |
965 | + MX7D_PAD_GPIO1_IO12__USB_OTG1_ID | MUX_PAD_CTRL(WEAK_PULLUP), | |
966 | + /* OTG1 Power Enable */ | |
967 | + MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), | |
968 | + /* OTG1 Over Current */ | |
969 | + MX7D_PAD_GPIO1_IO04__GPIO1_IO4 | MUX_PAD_CTRL(WEAK_PULLUP), | |
970 | + | |
971 | +}; | |
972 | + | |
973 | +static iomux_v3_cfg_t const usb_otg2_pads[] = { | |
974 | + /* OTG2 Power Enable */ | |
975 | + MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), | |
976 | + /* OTG2 Over Current */ | |
977 | + MX7D_PAD_GPIO1_IO06__GPIO1_IO6 | MUX_PAD_CTRL(WEAK_PULLUP), | |
978 | +}; | |
979 | + | |
980 | +static void setup_usb(void) | |
981 | +{ | |
982 | + imx_iomux_v3_setup_multiple_pads(usb_otg1_pads, | |
983 | + ARRAY_SIZE(usb_otg1_pads)); | |
984 | + gpio_direction_input(IMX_GPIO_NR(1, 4)); | |
985 | + | |
986 | + imx_iomux_v3_setup_multiple_pads(usb_otg2_pads, | |
987 | + ARRAY_SIZE(usb_otg2_pads)); | |
988 | + gpio_direction_input(IMX_GPIO_NR(1, 6)); | |
989 | +} | |
990 | + | |
991 | +int board_usb_phy_mode(int port) | |
992 | +{ | |
993 | + if (port == 0) | |
994 | + return usb_phy_mode(port); | |
995 | + else | |
996 | + return USB_INIT_HOST; | |
997 | +} | |
998 | +#endif | |
999 | + | |
1000 | +int board_early_init_f(void) | |
1001 | +{ | |
1002 | + setup_iomux_reset_out(); | |
1003 | + setup_iomux_uart6(); | |
1004 | + setup_iomux_uart2(); | |
1005 | + setup_iomux_uart7(); | |
1006 | + setup_iomux_uart3(); | |
1007 | + | |
1008 | +#ifdef CONFIG_SYS_I2C_MXC | |
1009 | + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); | |
1010 | + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); | |
1011 | + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3); | |
1012 | + setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4); | |
1013 | +#endif | |
1014 | + | |
1015 | +#ifdef CONFIG_MXC_SPI | |
1016 | + setup_spinor(); | |
1017 | +#endif | |
1018 | + | |
1019 | +#ifdef CONFIG_USB_EHCI_MX7 | |
1020 | + setup_usb(); | |
1021 | +#endif | |
1022 | + setup_iomux_spi1(); | |
1023 | + setup_iomux_spi3(); | |
1024 | + setup_iomux_flexcan1(); | |
1025 | + setup_iomux_flexcan2(); | |
1026 | + setup_iomux_gpios(); | |
1027 | + setup_iomux_lvds_ch_sel(); | |
1028 | + setup_iomux_misc(); | |
1029 | + | |
1030 | + return 0; | |
1031 | +} | |
1032 | + | |
1033 | +int board_init(void) | |
1034 | +{ | |
1035 | + /* address of boot parameters */ | |
1036 | + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; | |
1037 | + | |
1038 | +#ifdef CONFIG_FEC_MXC | |
1039 | + setup_fec(CONFIG_FEC_ENET_DEV); | |
1040 | +#endif | |
1041 | + | |
1042 | +#ifdef CONFIG_NAND_MXS | |
1043 | + setup_gpmi_nand(); | |
1044 | +#endif | |
1045 | + | |
1046 | +#ifdef CONFIG_FSL_QSPI | |
1047 | + board_qspi_init(); | |
1048 | +#endif | |
1049 | + | |
1050 | + return 0; | |
1051 | +} | |
1052 | + | |
1053 | +#ifdef CONFIG_CMD_BMODE | |
1054 | +static const struct boot_mode board_boot_modes[] = { | |
1055 | + /* 4 bit bus width */ | |
1056 | + {"sd1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, | |
1057 | + {"emmc", MAKE_CFGVAL(0x10, 0x2a, 0x00, 0x00)}, | |
1058 | + /* TODO: Nand */ | |
1059 | + {"qspi", MAKE_CFGVAL(0x00, 0x40, 0x00, 0x00)}, | |
1060 | + {NULL, 0}, | |
1061 | +}; | |
1062 | +#endif | |
1063 | + | |
1064 | +#ifdef CONFIG_POWER | |
1065 | +#define I2C_PMIC 0 | |
1066 | +int power_init_board(void) | |
1067 | +{ | |
1068 | + struct pmic *p; | |
1069 | + int ret; | |
1070 | + unsigned int reg, rev_id; | |
1071 | + | |
1072 | + ret = power_pfuze3000_init(I2C_PMIC); | |
1073 | + if (ret) | |
1074 | + return ret; | |
1075 | + | |
1076 | + p = pmic_get("PFUZE3000"); | |
1077 | + ret = pmic_probe(p); | |
1078 | + if (ret) | |
1079 | + return ret; | |
1080 | + | |
1081 | + pmic_reg_read(p, PFUZE3000_DEVICEID, ®); | |
1082 | + pmic_reg_read(p, PFUZE3000_REVID, &rev_id); | |
1083 | + printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id); | |
1084 | + | |
1085 | + /* disable Low Power Mode during standby mode */ | |
1086 | + pmic_reg_read(p, PFUZE3000_LDOGCTL, ®); | |
1087 | + reg |= 0x1; | |
1088 | + pmic_reg_write(p, PFUZE3000_LDOGCTL, reg); | |
1089 | + | |
1090 | + /* SW1A/1B mode set to APS/APS */ | |
1091 | + reg = 0x8; | |
1092 | + pmic_reg_write(p, PFUZE3000_SW1AMODE, reg); | |
1093 | + pmic_reg_write(p, PFUZE3000_SW1BMODE, reg); | |
1094 | + | |
1095 | + /* SW1A/1B standby voltage set to 0.975V */ | |
1096 | + reg = 0xb; | |
1097 | + pmic_reg_write(p, PFUZE3000_SW1ASTBY, reg); | |
1098 | + pmic_reg_write(p, PFUZE3000_SW1BSTBY, reg); | |
1099 | + | |
1100 | + /* decrease SW1B normal voltage to 0.975V */ | |
1101 | + pmic_reg_read(p, PFUZE3000_SW1BVOLT, ®); | |
1102 | + reg &= ~0x1f; | |
1103 | + reg |= PFUZE3000_SW1AB_SETP(975); | |
1104 | + pmic_reg_write(p, PFUZE3000_SW1BVOLT, reg); | |
1105 | + | |
1106 | + return 0; | |
1107 | +} | |
1108 | +#endif | |
1109 | + | |
1110 | +int board_late_init(void) | |
1111 | +{ | |
1112 | + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; | |
1113 | +#ifdef CONFIG_CMD_BMODE | |
1114 | + add_board_boot_modes(board_boot_modes); | |
1115 | +#endif | |
1116 | + | |
1117 | +#ifdef CONFIG_ENV_IS_IN_MMC | |
1118 | + board_late_mmc_env_init(); | |
1119 | +#endif | |
1120 | + | |
1121 | + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); | |
1122 | + | |
1123 | + set_wdog_reset(wdog); | |
1124 | + | |
1125 | +/* Check Board Information */ | |
1126 | + setup_i2c(1, CONFIG_SYS_I2C_SPEED, | |
1127 | + 0x50, &i2c_pad_info2); | |
1128 | + | |
1129 | + struct smarcfimx7_id header; | |
1130 | + | |
1131 | + if (read_eeprom(&header) < 0) | |
1132 | + puts("Could not get board ID.\n"); | |
1133 | + | |
1134 | + puts("---------Embedian SMARC-FiMX7------------\n"); | |
1135 | + printf("Board ID: %.*s\n", | |
1136 | + sizeof(header.name), header.name); | |
1137 | + printf("Board Revision: %.*s\n", | |
1138 | + sizeof(header.version), header.version); | |
1139 | + printf("Board Serial#: %.*s\n", | |
1140 | + sizeof(header.serial), header.serial); | |
1141 | + puts("-----------------------------------------\n"); | |
1142 | + | |
1143 | +/* SMARC BOOT_SEL*/ | |
1144 | + if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 0)) { | |
1145 | + puts("BOOT_SEL Detected: OFF OFF OFF, unsupported boot up device: SATA...\n"); | |
1146 | + hang(); | |
1147 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 1)) { | |
1148 | + puts("BOOT_SEL Detected: OFF OFF ON, unsupported boot up device: NAND...\n"); | |
1149 | + hang(); | |
1150 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 0)) { | |
1151 | + puts("BOOT_SEL Detected: OFF ON OFF, unsupported boot up device: Carrier eSPI...\n"); | |
1152 | + hang(); | |
1153 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 0)) { | |
1154 | + puts("BOOT_SEL Detected: ON OFF OFF, Load zImage from Carrier SD Card...\n"); | |
1155 | + setenv_ulong("mmcdev", 0); | |
1156 | + setenv("bootcmd", "mmc rescan; run loadbootenv; run importbootenv; run uenvcmd; run loadzimage; run loadfdt; run mmcboot;"); | |
1157 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 1)) { | |
1158 | + puts("BOOT_SEL Detected: OFF ON ON, Load zImage from Module eMMC Flash...\n"); | |
1159 | + setenv_ulong("mmcdev", 1); | |
1160 | + setenv("bootcmd", "mmc rescan; run loadbootenv; run importbootenv; run uenvcmd; run loadzimage; run loadfdt; run mmcboot;"); | |
1161 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 0)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 1)) { | |
1162 | + puts("BOOT_SEL Detected: ON OFF ON, Load zImage from GBE...\n"); | |
1163 | + setenv("bootcmd", "run netboot;"); | |
1164 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 0)) { | |
1165 | + puts("BOOT_SEL Detected: OFF ON OFF, unsupported boot up device: Carrier SPI...\n"); | |
1166 | + hang(); | |
1167 | + } else if ((gpio_get_value(IMX_GPIO_NR(5, 15)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 16)) == 1)&&(gpio_get_value(IMX_GPIO_NR(5, 17)) == 1)) { | |
1168 | + puts("BOOT_SEL Detected: ON ON ON, MOdule SPI Boot up is Default, Load zImage from Module eMMC...\n"); | |
1169 | + setenv_ulong("mmcdev", 1); | |
1170 | + setenv("bootcmd", "mmc rescan; run loadbootenv; run importbootenv; run uenvcmd; run loadzimage; run loadfdt; run mmcboot;"); | |
1171 | + } else { | |
1172 | + puts("unsupported boot devices\n"); | |
1173 | + hang(); | |
1174 | + } | |
1175 | + | |
1176 | + return 0; | |
1177 | +} | |
1178 | + | |
1179 | +#ifdef CONFIG_FSL_FASTBOOT | |
1180 | +void board_fastboot_setup(void) | |
1181 | +{ | |
1182 | + switch (get_boot_device()) { | |
1183 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1184 | + case SD1_BOOT: | |
1185 | + case MMC1_BOOT: | |
1186 | + if (!getenv("fastboot_dev")) | |
1187 | + setenv("fastboot_dev", "mmc0"); | |
1188 | + if (!getenv("bootcmd")) | |
1189 | + setenv("bootcmd", "boota mmc0"); | |
1190 | + break; | |
1191 | + case SD3_BOOT: | |
1192 | + case MMC3_BOOT: | |
1193 | + if (!getenv("fastboot_dev")) | |
1194 | + setenv("fastboot_dev", "mmc1"); | |
1195 | + if (!getenv("bootcmd")) | |
1196 | + setenv("bootcmd", "boota mmc1"); | |
1197 | + break; | |
1198 | +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | |
1199 | + default: | |
1200 | + printf("unsupported boot devices\n"); | |
1201 | + break; | |
1202 | + } | |
1203 | +} | |
1204 | + | |
1205 | +#ifdef CONFIG_ANDROID_RECOVERY | |
1206 | + | |
1207 | +/* Use LID# for recovery key */ | |
1208 | +#define GPIO_VOL_DN_KEY IMX_GPIO_NR(5, 10) | |
1209 | +iomux_v3_cfg_t const recovery_key_pads[] = { | |
1210 | + (MX7D_PAD_SD2_WP__GPIO5_IO10 | MUX_PAD_CTRL(BUTTON_PAD_CTRL)), | |
1211 | +}; | |
1212 | + | |
1213 | +int check_recovery_cmd_file(void) | |
1214 | +{ | |
1215 | + int button_pressed = 0; | |
1216 | + int recovery_mode = 0; | |
1217 | + | |
1218 | + recovery_mode = recovery_check_and_clean_flag(); | |
1219 | + | |
1220 | + /* Check Recovery Combo Button press or not. */ | |
1221 | + imx_iomux_v3_setup_multiple_pads(recovery_key_pads, | |
1222 | + ARRAY_SIZE(recovery_key_pads)); | |
1223 | + | |
1224 | + gpio_direction_input(GPIO_VOL_DN_KEY); | |
1225 | + | |
1226 | + if (gpio_get_value(GPIO_VOL_DN_KEY) == 0) { /* VOL_DN key is low assert */ | |
1227 | + button_pressed = 1; | |
1228 | + printf("Recovery key pressed\n"); | |
1229 | + } | |
1230 | + | |
1231 | + return recovery_mode || button_pressed; | |
1232 | +} | |
1233 | + | |
1234 | +void board_recovery_setup(void) | |
1235 | +{ | |
1236 | + int bootdev = get_boot_device(); | |
1237 | + | |
1238 | + switch (bootdev) { | |
1239 | +#if defined(CONFIG_FASTBOOT_STORAGE_MMC) | |
1240 | + case SD1_BOOT: | |
1241 | + case MMC1_BOOT: | |
1242 | + if (!getenv("bootcmd_android_recovery")) | |
1243 | + setenv("bootcmd_android_recovery", "boota mmc0 recovery"); | |
1244 | + break; | |
1245 | + case SD3_BOOT: | |
1246 | + case MMC3_BOOT: | |
1247 | + if (!getenv("bootcmd_android_recovery")) | |
1248 | + setenv("bootcmd_android_recovery", "boota mmc1 recovery"); | |
1249 | + break; | |
1250 | +#endif /*CONFIG_FASTBOOT_STORAGE_MMC*/ | |
1251 | + default: | |
1252 | + printf("Unsupported bootup device for recovery: dev: %d\n", | |
1253 | + bootdev); | |
1254 | + return; | |
1255 | + } | |
1256 | + | |
1257 | + printf("setup env for recovery..\n"); | |
1258 | + setenv("bootcmd", "run bootcmd_android_recovery"); | |
1259 | +} | |
1260 | +#endif /*CONFIG_ANDROID_RECOVERY*/ | |
1261 | + | |
1262 | +#endif /*CONFIG_FSL_FASTBOOT*/ |
board/embedian/smarcfimx7/smarcfimx7.h
1 | +/* | |
2 | + * smarcfimx7.h | |
3 | + * | |
4 | + * Embedian SMARC-FiMX7 boards information header | |
5 | + * | |
6 | + * Copyright (C) 2017, Embedian, Inc. - http://www.embedian.com/ | |
7 | + * | |
8 | + * SPDX-License-Identifier: GPL-2.0+ | |
9 | + */ | |
10 | + | |
11 | +#ifndef _SMARCFIMX7_H_ | |
12 | +#define _SMARCFIMX7_H_ | |
13 | +/* | |
14 | +* SMARC-FiMX7 Config held in module eeprom device. | |
15 | +* | |
16 | +* Header Format | |
17 | +* | |
18 | +* Name Size Contents | |
19 | +* (Bytes) | |
20 | +*------------------------------------------------------------- | |
21 | +* Header 4 0xAA, 0x55, 0x33, 0xEE | |
22 | +* | |
23 | +* Board Name 8 Name for board in ASCII. | |
24 | +* example "SMCMX7D1" = "SMARC-FiMX7 | |
25 | +* Dual Core and 1GB DDR3 memory". "SMCMX7S0" = | |
26 | +* SMARC-FiMX7 Computer on Module with solo Core | |
27 | +* and 512MB DDR3L Configuration | |
28 | +* | |
29 | +* Version 4 Hardware version code for board in | |
30 | +* in ASCII. "00A0" = rev.0A | |
31 | +* Serial Number 12 Serial number of the board. This is a 12 | |
32 | +* character string which is: WWYYMSkknnnn, where | |
33 | +* WW = 2 digit week of the year of production | |
34 | +* YY = 2 digit year of production | |
35 | +* kk = 2 digit module variants | |
36 | +* nnnn = incrementing board number | |
37 | +* Configuration Option 32 Codes to show the configuration | |
38 | +* setup on this board. | |
39 | +* MAC Address (LAN1) MAC Address for FEC controller | |
40 | +* MAC Address (LAN2, if any) MAC Address for 2nd LAN (if any) | |
41 | +* Available 32700 Available space for other non-volatile | |
42 | +* codes/data | |
43 | +*/ | |
44 | + | |
45 | +#define HDR_NO_OF_MAC_ADDR 3 | |
46 | +#define HDR_ETH_ALEN 6 | |
47 | +#define HDR_NAME_LEN 8 | |
48 | + | |
49 | +struct smarcfimx7_id { | |
50 | + unsigned int magic; | |
51 | + char name[HDR_NAME_LEN]; | |
52 | + char version[4]; | |
53 | + char serial[12]; | |
54 | + char config[32]; | |
55 | + char mac_addr[HDR_NO_OF_MAC_ADDR][HDR_ETH_ALEN]; | |
56 | +}; | |
57 | + | |
58 | +static inline int board_is_smcmx7s0(struct smarcfimx7_id *header) | |
59 | +{ | |
60 | + return !strncmp(header->name, "SMCMX7S0", HDR_NAME_LEN); | |
61 | +} | |
62 | + | |
63 | +static inline int board_is_smcmx7d1(struct smarcfimx7_id *header) | |
64 | +{ | |
65 | + return !strncmp(header->name, "SMCMX7D1", HDR_NAME_LEN); | |
66 | +} | |
67 | + | |
68 | +/* | |
69 | + * Read ethernet MAC address from EEPROM for SMARC-FiMX7 compatible boards. | |
70 | + * Returns 1 if found, 0 otherwise. | |
71 | + */ | |
72 | +int smarcfimx7_read_mac_address(uint8_t *buf) | |
73 | +{ | |
74 | +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR | |
75 | + /* Read MAC address. */ | |
76 | + i2c_set_bus_num(1); | |
77 | + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x3C, | |
78 | + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &buf[0], 6)) | |
79 | + goto i2cerr; | |
80 | + | |
81 | + /* Check that MAC address is valid. */ | |
82 | + if (!is_valid_ethaddr(buf)) | |
83 | + goto err; | |
84 | + | |
85 | + return 1; /* Found */ | |
86 | + | |
87 | +i2cerr: | |
88 | + printf("Read from EEPROM @ 0x%02x failed\n", | |
89 | + CONFIG_SYS_I2C_EEPROM_ADDR); | |
90 | +err: | |
91 | +#endif /* CONFIG_SYS_I2C_EEPROM_ADDR */ | |
92 | + | |
93 | + return 0; | |
94 | +} | |
95 | + | |
96 | +/* | |
97 | + * If there is no MAC address in the environment, then it will be initialized | |
98 | + * (silently) from the value in the EEPROM. | |
99 | + */ | |
100 | +void smarcfimx7_sync_env_enetaddr(uint8_t *rom_enetaddr) | |
101 | +{ | |
102 | + i2c_set_bus_num(1); | |
103 | + uint8_t env_enetaddr[6]; | |
104 | + int ret; | |
105 | + | |
106 | + ret = eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr); | |
107 | + if (!ret) { | |
108 | + /* | |
109 | + * There is no MAC address in the environment, so we | |
110 | + * initialize it from the value in the EEPROM. | |
111 | + */ | |
112 | + debug("### Setting environment from EEPROM MAC address = " | |
113 | + "\"%pM\"\n", | |
114 | + env_enetaddr); | |
115 | + ret = !eth_setenv_enetaddr("ethaddr", rom_enetaddr); | |
116 | + } | |
117 | + if (!ret) | |
118 | + printf("Failed to set mac address from EEPROM: %d\n", ret); | |
119 | +} | |
120 | + | |
121 | +int smarcfimx7_read_mac_address1(uint8_t *buf) | |
122 | +{ | |
123 | +#ifdef CONFIG_SYS_I2C_EEPROM_ADDR | |
124 | + /* Read MAC address. */ | |
125 | + i2c_set_bus_num(1); | |
126 | + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x42, | |
127 | + CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &buf[0], 6)) | |
128 | + goto i2cerr; | |
129 | + | |
130 | + /* Check that MAC address is valid. */ | |
131 | + if (!is_valid_ethaddr(buf)) | |
132 | + goto err; | |
133 | + | |
134 | + return 1; /* Found */ | |
135 | + | |
136 | +i2cerr: | |
137 | + printf("Read 2nd GBE MAC address from EEPROM @ 0x%02x failed\n", | |
138 | + CONFIG_SYS_I2C_EEPROM_ADDR); | |
139 | +err: | |
140 | +#endif /* CONFIG_SYS_I2C_EEPROM_ADDR */ | |
141 | + | |
142 | + return 0; | |
143 | +} | |
144 | + | |
145 | +/* | |
146 | + * If there is no MAC address in the environment, then it will be initialized | |
147 | + * (silently) from the value in the EEPROM. | |
148 | + */ | |
149 | +void smarcfimx7_sync_env_enet1addr(uint8_t *rom_enet1addr) | |
150 | +{ | |
151 | + i2c_set_bus_num(1); | |
152 | + uint8_t env_enet1addr[6]; | |
153 | + int ret; | |
154 | + | |
155 | + ret = eth_getenv_enetaddr_by_index("eth1", 0, env_enet1addr); | |
156 | + if (!ret) { | |
157 | + /* | |
158 | + * There is no MAC address in the environment, so we | |
159 | + * initialize it from the value in the EEPROM. | |
160 | + */ | |
161 | + debug("### Setting environment from EEPROM MAC address = " | |
162 | + "\"%pM\"\n", | |
163 | + env_enet1addr); | |
164 | + ret = !eth_setenv_enetaddr("eth1addr", rom_enet1addr); | |
165 | + } | |
166 | + if (!ret) | |
167 | + printf("Failed to set 2nd GBE mac address from EEPROM: %d\n", ret); | |
168 | +} | |
169 | + | |
170 | +#endif |
common/autoboot.c
... | ... | @@ -326,7 +326,7 @@ |
326 | 326 | s = getenv("bootdelay"); |
327 | 327 | bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; |
328 | 328 | |
329 | -#ifdef is_boot_from_usb | |
329 | +#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb) | |
330 | 330 | if (is_boot_from_usb()) { |
331 | 331 | disconnect_from_pc(); |
332 | 332 | printf("Boot from USB for mfgtools\n"); |
... | ... | @@ -364,7 +364,7 @@ |
364 | 364 | #endif /* CONFIG_BOOTCOUNT_LIMIT */ |
365 | 365 | s = getenv("bootcmd"); |
366 | 366 | |
367 | -#ifdef is_boot_from_usb | |
367 | +#if !defined(CONFIG_FSL_FASTBOOT) && defined(is_boot_from_usb) | |
368 | 368 | if (is_boot_from_usb()) { |
369 | 369 | s = getenv("bootcmd_mfg"); |
370 | 370 | printf("Run bootcmd_mfg: %s\n", s); |
configs/smarcfimx7d_ser0_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg,DEFAULT_FDT_FILE=\"imx7d-smarcfimx7.dtb\",SER0,MX7D,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7d_ser1_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg,DEFAULT_FDT_FILE=\"imx7d-smarcfimx7.dtb\",SER1,MX7D,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7d_ser2_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg,DEFAULT_FDT_FILE=\"imx7d-smarcfimx7.dtb\",SER2,MX7D,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7d_ser3_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7d_2x_k4b4g1646q.cfg,DEFAULT_FDT_FILE=\"imx7d-smarcfimx7.dtb\",SER3,MX7D,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7s_ser0_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg,DEFAULT_FDT_FILE=\"imx7s-smarcfimx7.dtb\",MX7S,SER0,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7s_ser1_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg,DEFAULT_FDT_FILE=\"imx7s-smarcfimx7.dtb\",MX7S,SER1,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7s_ser2_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg,DEFAULT_FDT_FILE=\"imx7s-smarcfimx7.dtb\",MX7S,SER2,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
configs/smarcfimx7s_ser3_defconfig
1 | +CONFIG_ARM=y | |
2 | +CONFIG_ARCH_MX7=y | |
3 | +CONFIG_TARGET_SMARCFIMX7=y | |
4 | +CONFIG_SYS_PROMPT="U-Boot# " | |
5 | +CONFIG_IMX_RDC=y | |
6 | +CONFIG_IMX_BOOTAUX=y | |
7 | +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/embedian/smarcfimx7/ddr3l/mx7s_2x_k4b2g1646q.cfg,DEFAULT_FDT_FILE=\"imx7s-smarcfimx7.dtb\",MX7S,SER3,SYS_USE_SPINOR" | |
8 | +CONFIG_CMD_GPIO=y | |
9 | +CONFIG_CMD_DHCP=y | |
10 | +CONFIG_CMD_PING=y |
drivers/mtd/spi/sf_params.c
... | ... | @@ -47,6 +47,7 @@ |
47 | 47 | {"MX25L1605D", 0xc22015, 0x0, 64 * 1024, 32, RD_NORM, 0}, |
48 | 48 | {"MX25L3205D", 0xc22016, 0x0, 64 * 1024, 64, RD_NORM, 0}, |
49 | 49 | {"MX25L6405D", 0xc22017, 0x0, 64 * 1024, 128, RD_NORM, 0}, |
50 | + {"MX25U3235F", 0xc22536, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K}, | |
50 | 51 | {"MX25L12805", 0xc22018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP}, |
51 | 52 | {"MX25L25635F", 0xc22019, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP}, |
52 | 53 | {"MX25L51235F", 0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP}, |
drivers/spi/fsl_qspi.c
... | ... | @@ -818,7 +818,7 @@ |
818 | 818 | writel(tmp, q->iobase + QUADSPI_TBDR); |
819 | 819 | } |
820 | 820 | |
821 | -#if defined(CONFIG_MX7D) || defined(CONFIG_MX6UL) | |
821 | +#if defined(CONFIG_MX7D) || defined(CONFIG_MX6UL) || defined(CONFIG_MX7S) | |
822 | 822 | u32 t3; |
823 | 823 | /* iMX7D and MX6UL TXFIFO must be at least 16 bytes*/ |
824 | 824 | t3 = t1 + ((t2 + 3) >> 2); |
include/config_distro_defaults.h
include/configs/mx7smarc_common.h
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * Configuration settings for the Freescale i.MX7. | |
5 | + * | |
6 | + * SPDX-License-Identifier: GPL-2.0+ | |
7 | + */ | |
8 | + | |
9 | +#ifndef __MX7_COMMON_H | |
10 | +#define __MX7_COMMON_H | |
11 | + | |
12 | +#include <linux/sizes.h> | |
13 | +#include <asm/arch/imx-regs.h> | |
14 | +#include <asm/imx-common/gpio.h> | |
15 | + | |
16 | +#ifndef CONFIG_MX7 | |
17 | +#define CONFIG_MX7 | |
18 | +#endif | |
19 | + | |
20 | +/* Timer settings */ | |
21 | +#define CONFIG_MXC_GPT_HCLK | |
22 | +#define CONFIG_SYSCOUNTER_TIMER | |
23 | +#define CONFIG_SC_TIMER_CLK 8000000 /* 8Mhz */ | |
24 | +#define CONFIG_SYS_FSL_CLK | |
25 | + | |
26 | +#define CONFIG_SYS_BOOTM_LEN 0x1000000 | |
27 | + | |
28 | +/* Enable iomux-lpsr support */ | |
29 | +#define CONFIG_IOMUX_LPSR | |
30 | +#define CONFIG_IMX_FIXED_IVT_OFFSET | |
31 | + | |
32 | +/* Size of malloc() pool */ | |
33 | +#define CONFIG_SYS_MALLOC_LEN (32 * SZ_1M) | |
34 | + | |
35 | +#define CONFIG_BOARD_EARLY_INIT_F | |
36 | +#define CONFIG_BOARD_LATE_INIT | |
37 | + | |
38 | +#define CONFIG_DISPLAY_CPUINFO | |
39 | + | |
40 | +#define CONFIG_CMDLINE_TAG | |
41 | + | |
42 | +#define CONFIG_FSL_CLK | |
43 | + | |
44 | +#define CONFIG_LOADADDR 0x80800000 | |
45 | +#define CONFIG_SYS_TEXT_BASE 0x87800000 | |
46 | + | |
47 | +#ifndef CONFIG_BOOTDELAY | |
48 | +#define CONFIG_BOOTDELAY 1 | |
49 | +#endif | |
50 | + | |
51 | +/* allow to overwrite serial and ethaddr */ | |
52 | +#define CONFIG_ENV_OVERWRITE | |
53 | +#define CONFIG_CONS_INDEX 1 | |
54 | +#define CONFIG_BAUDRATE 115200 | |
55 | + | |
56 | +/* Filesystems and image support */ | |
57 | +#define CONFIG_OF_LIBFDT | |
58 | +#define CONFIG_CMD_BOOTZ | |
59 | +#define CONFIG_DOS_PARTITION | |
60 | +#define CONFIG_CMD_EXT2 | |
61 | +#define CONFIG_CMD_EXT4 | |
62 | +#define CONFIG_CMD_EXT4_WRITE | |
63 | +#define CONFIG_CMD_FAT | |
64 | +#define CONFIG_FS_FAT | |
65 | +#define CONFIG_FS_EXT4 | |
66 | +#define CONFIG_EXT4_WRITE | |
67 | +#define CONFIG_CMD_PART | |
68 | +#define CONFIG_CMD_FS_GENERIC | |
69 | +#define CONFIG_DOS_PARTITION | |
70 | +#define CONFIG_PARTITION_UUIDS | |
71 | + | |
72 | +/* Miscellaneous configurable options */ | |
73 | +#undef CONFIG_CMD_IMLS | |
74 | +#define CONFIG_SYS_LONGHELP | |
75 | +#define CONFIG_SYS_HUSH_PARSER | |
76 | +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " | |
77 | +#define CONFIG_CMDLINE_EDITING | |
78 | +#define CONFIG_AUTO_COMPLETE | |
79 | +#define CONFIG_SYS_CBSIZE 512 | |
80 | +#define CONFIG_SYS_MAXARGS 32 | |
81 | +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE | |
82 | + | |
83 | +#ifndef CONFIG_SYS_DCACHE_OFF | |
84 | +#define CONFIG_CMD_CACHE | |
85 | +#endif | |
86 | + | |
87 | +/* GPIO */ | |
88 | +#define CONFIG_MXC_GPIO | |
89 | + | |
90 | +/* UART */ | |
91 | +#define CONFIG_MXC_UART | |
92 | +#if defined(CONFIG_SER0) | |
93 | +#define CONFIG_MXC_UART_BASE UART6_IPS_BASE_ADDR | |
94 | +#define CONFIG_CONSOLE_DEV "ttymxc5" | |
95 | +#endif | |
96 | +#if defined(CONFIG_SER1) | |
97 | +#define CONFIG_MXC_UART_BASE UART2_IPS_BASE_ADDR | |
98 | +#define CONFIG_CONSOLE_DEV "ttymxc1" | |
99 | +#endif | |
100 | +#if defined(CONFIG_SER2) | |
101 | +#define CONFIG_MXC_UART_BASE UART7_IPS_BASE_ADDR | |
102 | +#define CONFIG_CONSOLE_DEV "ttymxc6" | |
103 | +#endif | |
104 | +#if defined(CONFIG_SER3) | |
105 | +#define CONFIG_MXC_UART_BASE UART3_IPS_BASE_ADDR | |
106 | +#define CONFIG_CONSOLE_DEV "ttymxc2" | |
107 | +#endif | |
108 | + | |
109 | +/* MMC */ | |
110 | +#define CONFIG_MMC | |
111 | +#define CONFIG_CMD_MMC | |
112 | +#define CONFIG_GENERIC_MMC | |
113 | +#define CONFIG_BOUNCE_BUFFER | |
114 | +#define CONFIG_FSL_ESDHC | |
115 | +#define CONFIG_FSL_USDHC | |
116 | +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ | |
117 | + | |
118 | +/* Fuses */ | |
119 | +#define CONFIG_CMD_FUSE | |
120 | +#define CONFIG_MXC_OCOTP | |
121 | + | |
122 | +/* | |
123 | + * Default boot linux kernel in no secure mode. | |
124 | + * If want to boot kernel in secure mode, please define CONFIG_MX7_SEC | |
125 | + */ | |
126 | +#define CONFIG_MX7_SEC | |
127 | +#ifndef CONFIG_MX7_SEC | |
128 | +#define CONFIG_ARMV7_NONSEC | |
129 | +#define CONFIG_ARMV7_PSCI | |
130 | +#if defined(CONFIG_MX7D) | |
131 | +#define CONFIG_ARMV7_PSCI_NR_CPUS 2 | |
132 | +#else | |
133 | +#define CONFIG_ARMV7_PSCI_NR_CPUS 1 | |
134 | +#endif | |
135 | +#define CONFIG_ARMV7_SECURE_BASE 0x00900000 | |
136 | +#endif | |
137 | + | |
138 | +#endif |
include/configs/smarcfimx7.h
1 | +/* | |
2 | + * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. | |
3 | + * | |
4 | + * Configuration settings for the Freescale i.MX7D SABRESD board. | |
5 | + * | |
6 | + * SPDX-License-Identifier: GPL-2.0+ | |
7 | + */ | |
8 | + | |
9 | +#ifndef __SMARCFIMX7_CONFIG_H | |
10 | +#define __SMARCFIMX7_CONFIG_H | |
11 | + | |
12 | +#include "mx7smarc_common.h" | |
13 | + | |
14 | +#define CONFIG_DBG_MONITOR | |
15 | +#if defined(CONFIG_MX7D) | |
16 | +#define PHYS_SDRAM_SIZE SZ_1G | |
17 | +#else | |
18 | +#define PHYS_SDRAM_SIZE SZ_512M | |
19 | +#endif | |
20 | + | |
21 | +/* uncomment for PLUGIN mode support */ | |
22 | +/* #define CONFIG_USE_PLUGIN */ | |
23 | + | |
24 | +/* Uncomment to enable secure boot support */ | |
25 | +/* #define CONFIG_SECURE_BOOT */ | |
26 | + | |
27 | +#ifdef CONFIG_SECURE_BOOT | |
28 | +#ifndef CONFIG_CSF_SIZE | |
29 | +#define CONFIG_CSF_SIZE 0x4000 | |
30 | +#endif | |
31 | +#endif | |
32 | + | |
33 | +/* Network */ | |
34 | +#define CONFIG_CMD_MII | |
35 | +#define CONFIG_FEC_MXC | |
36 | +#define CONFIG_MII | |
37 | +#define CONFIG_FEC_XCV_TYPE RGMII | |
38 | +#define CONFIG_ETHPRIME "FEC" | |
39 | + | |
40 | +#define CONFIG_PHYLIB | |
41 | +#define CONFIG_PHY_ATHEROS | |
42 | + | |
43 | +#define CONFIG_FEC_ENET_DEV 0 | |
44 | + | |
45 | +#if (CONFIG_FEC_ENET_DEV == 0) | |
46 | +#define IMX_FEC_BASE ENET_IPS_BASE_ADDR | |
47 | +#define CONFIG_FEC_MXC_PHYADDR 0x6 | |
48 | +#elif (CONFIG_FEC_ENET_DEV == 1) | |
49 | +#define IMX_FEC_BASE ENET2_IPS_BASE_ADDR | |
50 | +#define CONFIG_FEC_MXC_PHYADDR 0x7 | |
51 | +#endif | |
52 | + | |
53 | +#define CONFIG_FEC_MXC_MDIO_BASE ENET_IPS_BASE_ADDR | |
54 | + | |
55 | +/* PMIC */ | |
56 | +#define CONFIG_POWER | |
57 | +#define CONFIG_POWER_I2C | |
58 | +#define CONFIG_POWER_PFUZE3000 | |
59 | +#define CONFIG_POWER_PFUZE3000_I2C_ADDR 0x08 | |
60 | + | |
61 | +#undef CONFIG_BOOTM_NETBSD | |
62 | +#undef CONFIG_BOOTM_PLAN9 | |
63 | +#undef CONFIG_BOOTM_RTEMS | |
64 | + | |
65 | +#undef CONFIG_CMD_EXPORTENV | |
66 | + | |
67 | +/* I2C configs */ | |
68 | +#define CONFIG_CMD_I2C | |
69 | +#define CONFIG_SYS_I2C | |
70 | +#define CONFIG_SYS_I2C_MXC | |
71 | +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ | |
72 | +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ | |
73 | +#define CONFIG_SYS_I2C_SPEED 100000 | |
74 | + | |
75 | +/* | |
76 | +* I2C EEPROM definitions EEPROM chip | |
77 | +*/ | |
78 | +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 | |
79 | +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 | |
80 | +#define CONFIG_MAC_ADDR_IN_EEPROM | |
81 | + | |
82 | +#ifdef CONFIG_SYS_BOOT_SPINOR | |
83 | +#define CONFIG_SYS_USE_SPINOR | |
84 | +#define CONFIG_ENV_IS_IN_SPI_FLASH | |
85 | +#elif defined CONFIG_SYS_BOOT_NAND | |
86 | +#define CONFIG_SYS_USE_NAND | |
87 | +#define CONFIG_ENV_IS_IN_NAND | |
88 | +#else | |
89 | +#define CONFIG_ENV_IS_IN_MMC | |
90 | +#endif | |
91 | + | |
92 | +#ifdef CONFIG_SYS_USE_SPINOR | |
93 | +#define CONFIG_CMD_SF | |
94 | +#define CONFIG_CMD_SPI | |
95 | +#define CONFIG_SPI_FLASH | |
96 | +#define CONFIG_SPI_FLASH_MACRONIX | |
97 | +#define CONFIG_MXC_SPI | |
98 | +#define CONFIG_SF_DEFAULT_BUS 1 | |
99 | +#define CONFIG_SF_DEFAULT_SPEED 20000000 | |
100 | +#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0) | |
101 | +#endif | |
102 | + | |
103 | +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ | |
104 | +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 | |
105 | + | |
106 | +#ifdef CONFIG_IMX_BOOTAUX | |
107 | +/* Set to SPI2 flash at default */ | |
108 | +#define CONFIG_SYS_AUXCORE_BOOTDATA 0x7F8000 /* Set to TCML address */ | |
109 | + | |
110 | +#ifdef CONFIG_SYS_USE_QSPI | |
111 | +#define UPDATE_M4_ENV \ | |
112 | + "m4image=m4_qspi.bin\0" \ | |
113 | + "loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image}\0" \ | |
114 | + "update_m4_from_sd=" \ | |
115 | + "if sf probe 0:0; then " \ | |
116 | + "if run loadm4image; then " \ | |
117 | + "setexpr fw_sz ${filesize} + 0xffff; " \ | |
118 | + "setexpr fw_sz ${fw_sz} / 0x10000; " \ | |
119 | + "setexpr fw_sz ${fw_sz} * 0x10000; " \ | |
120 | + "sf erase 0x100000 ${fw_sz}; " \ | |
121 | + "sf write ${loadaddr} 0x100000 ${filesize}; " \ | |
122 | + "fi; " \ | |
123 | + "fi\0" \ | |
124 | + "m4boot=sf probe 0:0; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0" | |
125 | +#else | |
126 | +#define UPDATE_M4_ENV \ | |
127 | + "m4image=m4_qspi.bin\0" \ | |
128 | + "loadm4image=fatload mmc ${mmcdev}:${mmcpart} "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)" ${m4image}\0" \ | |
129 | + "m4boot=run loadm4image; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0" | |
130 | +#endif | |
131 | +#else | |
132 | +#define UPDATE_M4_ENV "" | |
133 | +#endif | |
134 | + | |
135 | +#ifdef CONFIG_SYS_BOOT_NAND | |
136 | +#define CONFIG_MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(boot),16m(kernel),16m(dtb),-(rootfs) " | |
137 | +#else | |
138 | +#define CONFIG_MFG_NAND_PARTITION "" | |
139 | +#endif | |
140 | + | |
141 | +#define CONFIG_MFG_ENV_SETTINGS \ | |
142 | + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ | |
143 | + "rdinit=/linuxrc " \ | |
144 | + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ | |
145 | + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\ | |
146 | + "g_mass_storage.iSerialNumber=\"\" "\ | |
147 | + CONFIG_MFG_NAND_PARTITION \ | |
148 | + "clk_ignore_unused "\ | |
149 | + "\0" \ | |
150 | + "initrd_addr=0x83800000\0" \ | |
151 | + "initrd_high=0xffffffff\0" \ | |
152 | + "bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \ | |
153 | + | |
154 | +#define CONFIG_DFU_ENV_SETTINGS \ | |
155 | + "dfu_alt_info=image raw 0 0x800000;"\ | |
156 | + "u-boot raw 0 0x4000;"\ | |
157 | + "bootimg part 0 1;"\ | |
158 | + "rootfs part 0 2\0" \ | |
159 | + | |
160 | +#if defined(CONFIG_SYS_BOOT_NAND) | |
161 | +#define CONFIG_EXTRA_ENV_SETTINGS \ | |
162 | + CONFIG_MFG_ENV_SETTINGS \ | |
163 | + "panel=TFT43AB\0" \ | |
164 | + "fdt_addr=0x83000000\0" \ | |
165 | + "fdt_high=0xffffffff\0" \ | |
166 | + "console=ttymxc0\0" \ | |
167 | + "bootargs=console=ttymxc0,115200 ubi.mtd=3 " \ | |
168 | + "root=ubi0:rootfs rootfstype=ubifs " \ | |
169 | + "mtdparts=gpmi-nand:64m(boot),16m(kernel),16m(dtb),-(rootfs)\0"\ | |
170 | + "bootcmd=nand read ${loadaddr} 0x4000000 0x800000;"\ | |
171 | + "nand read ${fdt_addr} 0x5000000 0x100000;"\ | |
172 | + "bootz ${loadaddr} - ${fdt_addr}\0" | |
173 | + | |
174 | +#else | |
175 | +#define CONFIG_EXTRA_ENV_SETTINGS \ | |
176 | + UPDATE_M4_ENV \ | |
177 | + CONFIG_MFG_ENV_SETTINGS \ | |
178 | + CONFIG_DFU_ENV_SETTINGS \ | |
179 | + "script=boot.scr\0" \ | |
180 | + "image=zImage\0" \ | |
181 | + "console=" CONFIG_CONSOLE_DEV "\0" \ | |
182 | + "fdt_high=0xffffffff\0" \ | |
183 | + "initrd_high=0xffffffff\0" \ | |
184 | + "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ | |
185 | + "fdt_addr=0x83000000\0" \ | |
186 | + "ethprime=FEC0\0" \ | |
187 | + "fec.macaddr=${ethaddr}\0" \ | |
188 | + "fec1.macaddr=${eth1addr}\0" \ | |
189 | + "ipaddr=192.168.1.60\0" \ | |
190 | + "boot_fdt=try\0" \ | |
191 | + "ip_dyn=yes\0" \ | |
192 | + "panel=G070VW01\0" \ | |
193 | + "optargs= fec.macaddr=${ethaddr} fec1.macaddr=${eth1addr}\0" \ | |
194 | + "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ | |
195 | + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ | |
196 | + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ | |
197 | + "mmcrootfstype=ext4 rootwait\0" \ | |
198 | + "mmcautodetect=yes\0" \ | |
199 | + "mmcargs=setenv bootargs console=${console},${baudrate} " \ | |
200 | + "${optargs} " \ | |
201 | + "rootfstype=${mmcrootfstype} " \ | |
202 | + "root=${mmcroot}\0" \ | |
203 | + "loadbootenv=load mmc ${mmcdev}:${mmcpart} ${loadaddr} uEnv.txt\0" \ | |
204 | + "importbootenv=echo Importing environment from mmc (uEnv.txt)...; " \ | |
205 | + "env import -t $loadaddr $filesize\0" \ | |
206 | + "loadbootscript=" \ | |
207 | + "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ | |
208 | + "bootscript=echo Running bootscript from mmc ...; " \ | |
209 | + "source\0" \ | |
210 | + "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ | |
211 | + "loadzimage=load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ | |
212 | + "loadfdt=load mmc ${mmcdev}:${mmcpart} ${fdt_addr} /dtbs/${fdt_file}\0" \ | |
213 | + "mmcboot=echo Booting from mmc ...; " \ | |
214 | + "run mmcargs; " \ | |
215 | + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ | |
216 | + "if run loadfdt; then " \ | |
217 | + "bootz ${loadaddr} - ${fdt_addr}; " \ | |
218 | + "else " \ | |
219 | + "if test ${boot_fdt} = try; then " \ | |
220 | + "bootz; " \ | |
221 | + "else " \ | |
222 | + "echo WARN: Cannot load the DT; " \ | |
223 | + "fi; " \ | |
224 | + "fi; " \ | |
225 | + "else " \ | |
226 | + "bootz; " \ | |
227 | + "fi;\0" \ | |
228 | + "netargs=setenv bootargs console=${console},${baudrate} " \ | |
229 | + "root=/dev/nfs " \ | |
230 | + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ | |
231 | + "netboot=echo Booting from net ...; " \ | |
232 | + "run netargs; " \ | |
233 | + "if test ${ip_dyn} = yes; then " \ | |
234 | + "setenv get_cmd dhcp; " \ | |
235 | + "else " \ | |
236 | + "setenv get_cmd tftp; " \ | |
237 | + "fi; " \ | |
238 | + "${get_cmd} ${image}; " \ | |
239 | + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ | |
240 | + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ | |
241 | + "bootz ${loadaddr} - ${fdt_addr}; " \ | |
242 | + "else " \ | |
243 | + "if test ${boot_fdt} = try; then " \ | |
244 | + "bootz; " \ | |
245 | + "else " \ | |
246 | + "echo WARN: Cannot load the DT; " \ | |
247 | + "fi; " \ | |
248 | + "fi; " \ | |
249 | + "else " \ | |
250 | + "bootz; " \ | |
251 | + "fi;\0" | |
252 | + | |
253 | +#define CONFIG_BOOTCOMMAND \ | |
254 | + "mmc dev ${mmcdev};" \ | |
255 | + "if mmc rescan; then " \ | |
256 | + "echo SD/MMC found on device ${mmcdev};" \ | |
257 | + "if run loadbootenv; then " \ | |
258 | + "run importbootenv;" \ | |
259 | + "fi;" \ | |
260 | + "echo Checking if uenvcmd is set ...;" \ | |
261 | + "if test -n $uenvcmd; then " \ | |
262 | + "echo Running uenvcmd ...;" \ | |
263 | + "run uenvcmd;" \ | |
264 | + "fi;" \ | |
265 | + "echo Running default loadzimage ...;" \ | |
266 | + "if run loadzimage; then " \ | |
267 | + "run loadfdt;" \ | |
268 | + "run mmcboot;" \ | |
269 | + "fi;" \ | |
270 | + "else run netboot; fi" | |
271 | +#endif | |
272 | + | |
273 | +#define CONFIG_CMD_MEMTEST | |
274 | +#define CONFIG_SYS_MEMTEST_START 0x80000000 | |
275 | +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x20000000) | |
276 | + | |
277 | +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR | |
278 | +#define CONFIG_SYS_HZ 1000 | |
279 | + | |
280 | +#define CONFIG_STACKSIZE SZ_128K | |
281 | + | |
282 | +/* Physical Memory Map */ | |
283 | +#define CONFIG_NR_DRAM_BANKS 1 | |
284 | +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR | |
285 | + | |
286 | +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM | |
287 | +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR | |
288 | +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE | |
289 | + | |
290 | +#define CONFIG_SYS_INIT_SP_OFFSET \ | |
291 | + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) | |
292 | +#define CONFIG_SYS_INIT_SP_ADDR \ | |
293 | + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) | |
294 | + | |
295 | +/* FLASH and environment organization */ | |
296 | +#define CONFIG_SYS_NO_FLASH | |
297 | +#define CONFIG_ENV_SIZE SZ_8K | |
298 | + | |
299 | +/* | |
300 | + * If want to use nand, define CONFIG_NAND_MXS and rework board | |
301 | + * to support nand, since emmc has pin conflicts with nand | |
302 | + */ | |
303 | +#ifdef CONFIG_SYS_USE_NAND | |
304 | +#define CONFIG_CMD_NAND | |
305 | +#define CONFIG_CMD_NAND_TRIMFFS | |
306 | + | |
307 | +/* NAND stuff */ | |
308 | +#define CONFIG_NAND_MXS | |
309 | +#define CONFIG_SYS_MAX_NAND_DEVICE 1 | |
310 | +#define CONFIG_SYS_NAND_BASE 0x40000000 | |
311 | +#define CONFIG_SYS_NAND_5_ADDR_CYCLE | |
312 | +#define CONFIG_SYS_NAND_ONFI_DETECTION | |
313 | + | |
314 | +/* DMA stuff, needed for GPMI/MXS NAND support */ | |
315 | +#define CONFIG_APBH_DMA | |
316 | +#define CONFIG_APBH_DMA_BURST | |
317 | +#define CONFIG_APBH_DMA_BURST8 | |
318 | +#endif | |
319 | + | |
320 | +#ifdef CONFIG_SYS_USE_QSPI | |
321 | +#define CONFIG_FSL_QSPI | |
322 | +#define CONFIG_CMD_SF | |
323 | +#define CONFIG_SPI_FLASH | |
324 | +#define CONFIG_SPI_FLASH_MACRONIX | |
325 | +#define CONFIG_SPI_FLASH_BAR | |
326 | +#define CONFIG_SF_DEFAULT_BUS 0 | |
327 | +#define CONFIG_SF_DEFAULT_CS 0 | |
328 | +#define CONFIG_SF_DEFAULT_SPEED 40000000 | |
329 | +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 | |
330 | +#define CONFIG_QSPI_BASE QSPI1_IPS_BASE_ADDR | |
331 | +#define CONFIG_QSPI_MEMMAP_BASE QSPI0_ARB_BASE_ADDR | |
332 | +#endif | |
333 | + | |
334 | +#if defined(CONFIG_ENV_IS_IN_MMC) | |
335 | +#define CONFIG_ENV_OFFSET (12 * SZ_64K) | |
336 | +#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) | |
337 | +#define CONFIG_ENV_OFFSET (768 * 1024) | |
338 | +#define CONFIG_ENV_SECT_SIZE (64 * 1024) | |
339 | +#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS | |
340 | +#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS | |
341 | +#define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE | |
342 | +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED | |
343 | +#elif defined(CONFIG_ENV_IS_IN_NAND) | |
344 | +#undef CONFIG_ENV_SIZE | |
345 | +#define CONFIG_ENV_OFFSET (60 << 20) | |
346 | +#define CONFIG_ENV_SECT_SIZE (128 << 10) | |
347 | +#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE | |
348 | +#endif | |
349 | + | |
350 | +#ifdef CONFIG_SYS_USE_NAND | |
351 | +#define CONFIG_SYS_FSL_USDHC_NUM 1 | |
352 | +#else | |
353 | +#define CONFIG_SYS_FSL_USDHC_NUM 2 | |
354 | +#endif | |
355 | + | |
356 | +/* MMC Config*/ | |
357 | +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 | |
358 | +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC3 */ | |
359 | +#define CONFIG_SYS_MMC_ENV_PART 0 /* user area */ | |
360 | +#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC3 */ | |
361 | +/*#if defined(CONFIG_MX7D) | |
362 | +#define CONFIG_DEFAULT_FDT_FILE "imx7d-smarcfimx7.dtb" | |
363 | +#endif*/ | |
364 | + | |
365 | +/* USB Configs */ | |
366 | +#define CONFIG_CMD_USB | |
367 | +#define CONFIG_USB_EHCI | |
368 | +#define CONFIG_USB_EHCI_MX7 | |
369 | +#define CONFIG_USB_STORAGE | |
370 | +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET | |
371 | +#define CONFIG_USB_HOST_ETHER | |
372 | +#define CONFIG_USB_ETHER_ASIX | |
373 | +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) | |
374 | +#define CONFIG_MXC_USB_FLAGS 0 | |
375 | +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 | |
376 | + | |
377 | +#define CONFIG_IMX_THERMAL | |
378 | + | |
379 | +#define CONFIG_CMD_BMODE | |
380 | + | |
381 | +#define CONFIG_VIDEO | |
382 | +#ifdef CONFIG_VIDEO | |
383 | +#define CONFIG_CFB_CONSOLE | |
384 | +#define CONFIG_VIDEO_MXS | |
385 | +#define CONFIG_VIDEO_LOGO | |
386 | +#define CONFIG_VIDEO_SW_CURSOR | |
387 | +#define CONFIG_VGA_AS_SINGLE_DEVICE | |
388 | +#define CONFIG_SYS_CONSOLE_IS_IN_ENV | |
389 | +#define CONFIG_SPLASH_SCREEN | |
390 | +#define CONFIG_SPLASH_SCREEN_ALIGN | |
391 | +#define CONFIG_CMD_BMP | |
392 | +#define CONFIG_BMP_16BPP | |
393 | +#define CONFIG_VIDEO_BMP_RLE8 | |
394 | +#define CONFIG_VIDEO_BMP_LOGO | |
395 | +#define CONFIG_IMX_VIDEO_SKIP | |
396 | +#endif | |
397 | + | |
398 | +/* #define CONFIG_SPLASH_SCREEN*/ | |
399 | +/* #define CONFIG_MXC_EPDC*/ | |
400 | + | |
401 | +/* | |
402 | + * SPLASH SCREEN Configs | |
403 | + */ | |
404 | +#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_MXC_EPDC) | |
405 | +/* | |
406 | + * Framebuffer and LCD | |
407 | + */ | |
408 | +#define CONFIG_CFB_CONSOLE | |
409 | +#define CONFIG_CMD_BMP | |
410 | +#define CONFIG_LCD | |
411 | +#define CONFIG_SYS_CONSOLE_IS_IN_ENV | |
412 | + | |
413 | +#undef LCD_TEST_PATTERN | |
414 | +/* #define CONFIG_SPLASH_IS_IN_MMC 1 */ | |
415 | +#define LCD_BPP LCD_MONOCHROME | |
416 | +/* #define CONFIG_SPLASH_SCREEN_ALIGN 1 */ | |
417 | + | |
418 | +#define CONFIG_WAVEFORM_BUF_SIZE 0x400000 | |
419 | +#endif | |
420 | + | |
421 | +#if defined(CONFIG_MXC_EPDC) && defined(CONFIG_SYS_USE_QSPI) | |
422 | +#error "EPDC Pins conflicts QSPI, Either EPDC or QSPI can be enabled!" | |
423 | +#endif | |
424 | + | |
425 | +#if defined(CONFIG_ANDROID_SUPPORT) | |
426 | +#include "mx7dsabresdandroid.h" | |
427 | +#else | |
428 | +#define CONFIG_CI_UDC | |
429 | +#define CONFIG_USBD_HS | |
430 | +#define CONFIG_USB_GADGET_DUALSPEED | |
431 | + | |
432 | +#define CONFIG_USB_GADGET | |
433 | +#define CONFIG_CMD_USB_MASS_STORAGE | |
434 | +#define CONFIG_USB_FUNCTION_MASS_STORAGE | |
435 | +#define CONFIG_USB_GADGET_DOWNLOAD | |
436 | +#define CONFIG_USB_GADGET_VBUS_DRAW 2 | |
437 | + | |
438 | +#define CONFIG_G_DNL_VENDOR_NUM 0x0525 | |
439 | +#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5 | |
440 | +#define CONFIG_G_DNL_MANUFACTURER "FSL" | |
441 | + | |
442 | +/* USB Device Firmware Update support */ | |
443 | +#define CONFIG_CMD_DFU | |
444 | +#define CONFIG_USB_FUNCTION_DFU | |
445 | +#define CONFIG_DFU_MMC | |
446 | +#define CONFIG_DFU_RAM | |
447 | +#endif | |
448 | + | |
449 | +#endif /* __CONFIG_H */ |