diff options
author | Tom Rini <trini@konsulko.com> | 2019-11-04 12:57:41 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2019-11-04 12:57:41 -0500 |
commit | 73b6e6ad254b36763419cdd3fdf406c0094517b7 (patch) | |
tree | f432e1b568809834c52389b5075815700bc68026 /arch/arm/mach-imx | |
parent | 3b02d614b429442333ec3d82eef0bba527be4f8c (diff) | |
parent | ae8a53ece0ff3b1ed686c3e0af14e59973d25db8 (diff) |
Merge tag 'u-boot-imx-20191104' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20191104
-------------------
- i.MX NAND: nandbcb support for MX6UL / i.MX7
- i.MX8: support for HAB
- Convert to DM (opos6ul, mccmon6)
- Toradex i.MX6ull colibri
- sync DTS with kernel
Travis : https://travis-ci.org/sbabic/u-boot-imx/builds/606853416
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r-- | arch/arm/mach-imx/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/mach-imx/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/cmd_nandbcb.c | 377 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8/Kconfig | 12 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8/ahab.c | 347 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8/misc.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8/parse-container.c | 95 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8m/clock_imx8mq.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx8m/soc.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx_bootaux.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/init.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx6/Kconfig | 26 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx6/clock.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx6/opos6ul.c | 76 | ||||
-rw-r--r-- | arch/arm/mach-imx/sip.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/spl.c | 29 |
16 files changed, 892 insertions, 170 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index b0b9d2c070..3f93fe5174 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -81,7 +81,8 @@ config CMD_HDMIDETECT config CMD_NANDBCB bool "i.MX6 NAND Boot Control Block(BCB) command" depends on NAND && CMD_MTDPARTS - default y if ARCH_MX6 && NAND_MXS + select BCH if MX6UL || MX6ULL + default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS) help Unlike normal 'nand write/erase' commands, this command update Boot Control Block(BCB) for i.MX6 platform NAND IP's. diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 9dfe883ead..6e87dc58a0 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -155,10 +155,8 @@ ifeq ($(DEPFILE_EXISTS),0) endif flash.bin: spl/u-boot-spl-ddr.bin u-boot.itb FORCE -ifeq ($(DEPFILE_EXISTS),0) $(call if_changed,mkimage) endif -endif ifeq ($(CONFIG_ARCH_IMX8), y) SPL: diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 7811c61d22..09c4356529 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -14,8 +14,10 @@ #include <asm/io.h> #include <jffs2/jffs2.h> +#include <linux/bch.h> #include <linux/mtd/mtd.h> +#include <asm/arch/sys_proto.h> #include <asm/mach-imx/imx-nandbcb.h> #include <asm/mach-imx/imximage.cfg> #include <mxs_nand.h> @@ -25,6 +27,68 @@ #define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET) #define GETBIT(v, n) (((v) >> (n)) & 0x1) +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) +static uint8_t reverse_bit(uint8_t b) +{ + b = (b & 0xf0) >> 4 | (b & 0x0f) << 4; + b = (b & 0xcc) >> 2 | (b & 0x33) << 2; + b = (b & 0xaa) >> 1 | (b & 0x55) << 1; + + return b; +} + +static void encode_bch_ecc(void *buf, struct fcb_block *fcb, int eccbits) +{ + int i, j, m = 13; + int blocksize = 128; + int numblocks = 8; + int ecc_buf_size = (m * eccbits + 7) / 8; + struct bch_control *bch = init_bch(m, eccbits, 0); + u8 *ecc_buf = kzalloc(ecc_buf_size, GFP_KERNEL); + u8 *tmp_buf = kzalloc(blocksize * numblocks, GFP_KERNEL); + u8 *psrc, *pdst; + + /* + * The blocks here are bit aligned. If eccbits is a multiple of 8, + * we just can copy bytes. Otherwiese we must move the blocks to + * the next free bit position. + */ + WARN_ON(eccbits % 8); + + memcpy(tmp_buf, fcb, sizeof(*fcb)); + + for (i = 0; i < numblocks; i++) { + memset(ecc_buf, 0, ecc_buf_size); + psrc = tmp_buf + i * blocksize; + pdst = buf + i * (blocksize + ecc_buf_size); + + /* copy data byte aligned to destination buf */ + memcpy(pdst, psrc, blocksize); + + /* + * imx-kobs use a modified encode_bch which reverse the + * bit order of the data before calculating bch. + * Do this in the buffer and use the bch lib here. + */ + for (j = 0; j < blocksize; j++) + psrc[j] = reverse_bit(psrc[j]); + + encode_bch(bch, psrc, blocksize, ecc_buf); + + /* reverse ecc bit */ + for (j = 0; j < ecc_buf_size; j++) + ecc_buf[j] = reverse_bit(ecc_buf[j]); + + /* Here eccbuf is byte aligned and we can just copy it */ + memcpy(pdst + blocksize, ecc_buf, ecc_buf_size); + } + + kfree(ecc_buf); + kfree(tmp_buf); + free_bch(bch); +} +#else + static u8 calculate_parity_13_8(u8 d) { u8 p = 0; @@ -50,6 +114,7 @@ static void encode_hamming_13_8(void *_src, void *_ecc, size_t size) for (i = 0; i < size; i++) ecc[i] = calculate_parity_13_8(src[i]); } +#endif static u32 calc_chksum(void *buf, size_t size) { @@ -63,30 +128,41 @@ static u32 calc_chksum(void *buf, size_t size) return ~chksum; } -static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) +static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, + u32 fw1_start, u32 fw2_start, u32 fw_pages) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct mxs_nand_layout l; + + mxs_nand_get_layout(mtd, &l); fcb->fingerprint = FCB_FINGERPRINT; fcb->version = FCB_VERSION_1; + fcb->pagesize = mtd->writesize; fcb->oob_pagesize = mtd->writesize + mtd->oobsize; fcb->sectors = mtd->erasesize / mtd->writesize; - /* Divide ECC strength by two and save the value into FCB structure. */ - fcb->ecc_level = nand_info->bch_geometry.ecc_strength >> 1; - - fcb->ecc_type = fcb->ecc_level; + fcb->meta_size = l.meta_size; + fcb->nr_blocks = l.nblocks; + fcb->ecc_nr = l.data0_size; + fcb->ecc_level = l.ecc0; + fcb->ecc_size = l.datan_size; + fcb->ecc_type = l.eccn; /* Also hardcoded in kobs-ng */ - fcb->ecc_nr = 0x00000200; - fcb->ecc_size = 0x00000200; - fcb->datasetup = 80; - fcb->datahold = 60; - fcb->addr_setup = 25; - fcb->dsample_time = 6; - fcb->meta_size = 10; + if (is_mx6()) { + fcb->datasetup = 80; + fcb->datahold = 60; + fcb->addr_setup = 25; + fcb->dsample_time = 6; + } else if (is_mx7()) { + fcb->datasetup = 10; + fcb->datahold = 7; + fcb->addr_setup = 15; + fcb->dsample_time = 6; + } /* DBBT search area starts at second page on first block */ fcb->dbbt_start = 1; @@ -98,6 +174,14 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1; + fcb->disbbm = 0; + fcb->disbbm_search = 0; + + fcb->fw1_start = fw1_start; /* Firmware image starts on this sector */ + fcb->fw2_start = fw2_start; /* Secondary FW Image starting Sector */ + fcb->fw1_pages = fw_pages; /* Number of sectors in firmware image */ + fcb->fw2_pages = fw_pages; /* Number of sector in secondary FW image */ + fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); } @@ -121,6 +205,114 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) return n_bad_blocks; } +static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, + struct dbbt_block *dbbt, void *dbbt_data_page, + loff_t off) +{ + void *fcb_raw_page = 0; + int i, ret; + size_t dummy; + + /* + * We prepare raw page only for i.MX6, for i.MX7 we + * leverage BCH hw module instead + */ + if (is_mx6()) { + /* write fcb/dbbt */ + fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, + GFP_KERNEL); + if (!fcb_raw_page) { + debug("failed to allocate fcb_raw_page\n"); + ret = -ENOMEM; + return ret; + } + +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) + /* 40 bit BCH, for i.MX6UL(L) */ + encode_bch_ecc(fcb_raw_page + 32, fcb, 40); +#else + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, + fcb_raw_page + 12 + 512, 512); +#endif + /* + * Set the first and second byte of OOB data to 0xFF, + * not 0x00. These bytes are used as the Manufacturers Bad + * Block Marker (MBBM). Since the FCB is mostly written to + * the first page in a block, a scan for + * factory bad blocks will detect these blocks as bad, e.g. + * when function nand_scan_bbt() is executed to build a new + * bad block table. + */ + memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + } + for (i = 0; i < 2; i++) { + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", i); + continue; + } + + /* + * User BCH ECC hardware module for i.MX7 + */ + if (is_mx7()) { + u32 off = i * mtd->erasesize; + size_t rwsize = sizeof(*fcb); + + printf("Writing %d bytes to 0x%x: ", rwsize, off); + + /* switch nand BCH to FCB compatible settings */ + mxs_nand_mode_fcb(mtd); + ret = nand_write(mtd, off, &rwsize, + (unsigned char *)fcb); + mxs_nand_mode_normal(mtd); + + printf("%s\n", ret ? "ERROR" : "OK"); + } else if (is_mx6()) { + /* raw write */ + mtd_oob_ops_t ops = { + .datbuf = (u8 *)fcb_raw_page, + .oobbuf = ((u8 *)fcb_raw_page) + + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, + .mode = MTD_OPS_RAW + }; + + ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); + if (ret) + goto fcb_raw_page_err; + debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", + mtd->erasesize * i, ops.len, ret ? + "ERROR" : "OK"); + } + + ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, + mtd->writesize, &dummy, (void *)dbbt); + if (ret) + goto fcb_raw_page_err; + debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", + mtd->erasesize * i + mtd->writesize, dummy, + ret ? "ERROR" : "OK"); + + /* dbbtpages == 0 if no bad blocks */ + if (dbbt->dbbtpages > 0) { + loff_t to = (mtd->erasesize * i + mtd->writesize * 5); + + ret = mtd_write(mtd, to, mtd->writesize, &dummy, + dbbt_data_page); + if (ret) + goto fcb_raw_page_err; + } + } + +fcb_raw_page_err: + if (is_mx6()) + kfree(fcb_raw_page); + + return ret; +} + static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, size_t maxsize, const u_char *buf) { @@ -128,10 +320,11 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, struct fcb_block *fcb; struct dbbt_block *dbbt; loff_t fw1_off; - void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page; + void *fwbuf, *dbbt_page, *dbbt_data_page; + u32 fw1_start, fw1_pages; int nr_blks, nr_blks_fcb, fw1_blk; - size_t fwsize, dummy; - int i, ret; + size_t fwsize; + int ret; /* erase */ memset(&opts, 0, sizeof(opts)); @@ -194,9 +387,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, goto fwbuf_err; } - fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; - fcb->fw1_pages = size / mtd->writesize + 1; - fill_fcb(fcb, mtd); + fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; + fw1_pages = size / mtd->writesize + 1; + fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); @@ -223,77 +416,103 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, else if (ret > 0) dbbt->dbbtpages = 1; - /* write fcb/dbbt */ - fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); - if (!fcb_raw_page) { - debug("failed to allocate fcb_raw_page\n"); - ret = -ENOMEM; - goto dbbt_data_page_err; + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, off); + if (ret < 0) + printf("failed to write FCB/DBBT\n"); + +dbbt_data_page_err: + kfree(dbbt_data_page); +dbbt_page_err: + kfree(dbbt_page); +fcb_err: + kfree(fcb); +fwbuf_err: + kfree(fwbuf); +err: + return ret; +} + +static int do_nandbcb_bcbonly(int argc, char * const argv[]) +{ + struct fcb_block *fcb; + struct dbbt_block *dbbt; + u32 fw_len, fw1_off, fw2_off; + struct mtd_info *mtd; + void *dbbt_page, *dbbt_data_page; + int dev, ret; + + dev = nand_curr_device; + if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || + (!get_nand_dev_by_index(dev))) { + puts("No devices available\n"); + return CMD_RET_FAILURE; } - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512); - /* - * Set the first and second byte of OOB data to 0xFF, not 0x00. These - * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since - * the FCB is mostly written to the first page in a block, a scan for - * factory bad blocks will detect these blocks as bad, e.g. when - * function nand_scan_bbt() is executed to build a new bad block table. - */ - memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + mtd = get_nand_dev_by_index(dev); - for (i = 0; i < nr_blks_fcb; i++) { - if (mtd_block_isbad(mtd, off)) { - printf("Block %d is bad, skipped\n", i); - continue; - } + if (argc < 3) + return CMD_RET_FAILURE; - /* raw write */ - mtd_oob_ops_t ops = { - .datbuf = (u8 *)fcb_raw_page, - .oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize, - .len = mtd->writesize, - .ooblen = mtd->oobsize, - .mode = MTD_OPS_RAW - }; + fw_len = simple_strtoul(argv[1], NULL, 16); + fw1_off = simple_strtoul(argv[2], NULL, 16); - ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); - if (ret) - goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK"); + if (argc > 3) + fw2_off = simple_strtoul(argv[3], NULL, 16); + else + fw2_off = fw1_off; - ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, - mtd->writesize, &dummy, dbbt_page); - if (ret) - goto fcb_raw_page_err; - debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i + mtd->writesize, dummy, - ret ? "ERROR" : "OK"); + /* fill fcb */ + fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); + if (!fcb) { + debug("failed to allocate fcb\n"); + ret = -ENOMEM; + return CMD_RET_FAILURE; + } - /* dbbtpages == 0 if no bad blocks */ - if (dbbt->dbbtpages > 0) { - loff_t to = (mtd->erasesize * i + mtd->writesize * 5); + fill_fcb(fcb, mtd, fw1_off / mtd->writesize, + fw2_off / mtd->writesize, fw_len / mtd->writesize); - ret = mtd_write(mtd, to, mtd->writesize, &dummy, - dbbt_data_page); - if (ret) - goto fcb_raw_page_err; - } + /* fill dbbt */ + dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_page) { + debug("failed to allocate dbbt_page\n"); + ret = -ENOMEM; + goto fcb_err; } -fcb_raw_page_err: - kfree(fcb_raw_page); + dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_data_page) { + debug("failed to allocate dbbt_data_page\n"); + ret = -ENOMEM; + goto dbbt_page_err; + } + + dbbt = dbbt_page; + dbbt->checksum = 0; + dbbt->fingerprint = DBBT_FINGERPRINT2; + dbbt->version = DBBT_VERSION_1; + ret = dbbt_fill_data(mtd, dbbt_data_page, 0); + if (ret < 0) + goto dbbt_data_page_err; + else if (ret > 0) + dbbt->dbbtpages = 1; + + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, 0); dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: kfree(dbbt_page); fcb_err: kfree(fcb); -fwbuf_err: - kfree(fwbuf); -err: - return ret; + + if (ret < 0) { + printf("failed to write FCB/DBBT\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; } static int do_nandbcb_update(int argc, char * const argv[]) @@ -310,7 +529,7 @@ static int do_nandbcb_update(int argc, char * const argv[]) dev = nand_curr_device; if (dev < 0) { - printf("failed to get nand_curr_device, run nand device"); + printf("failed to get nand_curr_device, run nand device\n"); return CMD_RET_FAILURE; } @@ -352,6 +571,11 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, goto done; } + if (strcmp(cmd, "bcbonly") == 0) { + ret = do_nandbcb_bcbonly(argc, argv); + goto done; + } + done: if (ret != -1) return ret; @@ -362,7 +586,10 @@ usage: #ifdef CONFIG_SYS_LONGHELP static char nandbcb_help_text[] = "update addr off|partition len - update 'len' bytes starting at\n" - " 'off|part' to memory address 'addr', skipping bad blocks"; + " 'off|part' to memory address 'addr', skipping bad blocks\n" + "bcbonly fw-size fw1-off [fw2-off] - write only BCB (FCB and DBBT)\n" + " where `fw-size` is fw sizes in bytes, `fw1-off` and\n" + " and `fw2-off` - firmware offsets "; #endif U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb, diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index d17760e333..cdb78afacf 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -1,5 +1,10 @@ if ARCH_IMX8 +config AHAB_BOOT + bool "Support i.MX8 AHAB features" + help + This option enables the support for AHAB secure boot. + config IMX8 bool @@ -55,6 +60,12 @@ config TARGET_IMX8QM_MEK select BOARD_LATE_INIT select IMX8QM +config TARGET_IMX8QM_ROM7720_A1 + bool "Support i.MX8QM ROM-7720-A1" + select BOARD_LATE_INIT + select SUPPORT_SPL + select IMX8QM + config TARGET_IMX8QXP_MEK bool "Support i.MX8QXP MEK board" select BOARD_LATE_INIT @@ -64,6 +75,7 @@ endchoice source "board/freescale/imx8qm_mek/Kconfig" source "board/freescale/imx8qxp_mek/Kconfig" +source "board/advantech/imx8qm_rom7720_a1/Kconfig" source "board/toradex/apalis-imx8/Kconfig" source "board/toradex/colibri-imx8x/Kconfig" diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c new file mode 100644 index 0000000000..cf3c7d762a --- /dev/null +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + */ + +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/arch/sci/sci.h> +#include <asm/mach-imx/sys_proto.h> +#include <asm/arch-imx/cpu.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/image.h> +#include <console.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define SEC_SECURE_RAM_BASE (0x31800000UL) +#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) +#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL) + +#define SECO_PT 2U + +static inline bool check_in_dram(ulong addr) +{ + int i; + bd_t *bd = gd->bd; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + if (bd->bi_dram[i].size) { + if (addr >= bd->bi_dram[i].start && + addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) + return true; + } + } + + return false; +} + +int authenticate_os_container(ulong addr) +{ + struct container_hdr *phdr; + int i, ret = 0; + int err; + sc_rm_mr_t mr; + sc_faddr_t start, end; + u16 length; + struct boot_img_t *img; + unsigned long s, e; + + if (addr % 4) { + puts("Error: Image's address is not 4 byte aligned\n"); + return -EINVAL; + } + + if (!check_in_dram(addr)) { + puts("Error: Image's address is invalid\n"); + return -EINVAL; + } + + phdr = (struct container_hdr *)addr; + if (phdr->tag != 0x87 && phdr->version != 0x0) { + printf("Error: Wrong container header\n"); + return -EFAULT; + } + + if (!phdr->num_images) { + printf("Error: Wrong container, no image found\n"); + return -EFAULT; + } + + length = phdr->length_lsb + (phdr->length_msb << 8); + + debug("container length %u\n", length); + memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + err = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + if (err) { + printf("Authenticate container hdr failed, return %d\n", + err); + ret = -EIO; + goto exit; + } + + /* Copy images to dest address */ + for (i = 0; i < phdr->num_images; i++) { + img = (struct boot_img_t *)(addr + + sizeof(struct container_hdr) + + i * sizeof(struct boot_img_t)); + + debug("img %d, dst 0x%llx, src 0x%lx, size 0x%x\n", + i, img->dst, img->offset + addr, img->size); + + memcpy((void *)img->dst, (const void *)(img->offset + addr), + img->size); + + s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); + e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE); + + flush_dcache_range(s, e); + + /* Find the memreg and set permission for seco pt */ + err = sc_rm_find_memreg(-1, &mr, s, e); + if (err) { + printf("Not found memreg for image: %d, error %d\n", + i, err); + ret = -ENOMEM; + goto exit; + } + + err = sc_rm_get_memreg_info(-1, mr, &start, &end); + if (!err) + debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + + err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, + SC_RM_PERM_FULL); + if (err) { + printf("Set permission failed for img %d, error %d\n", + i, err); + ret = -EPERM; + goto exit; + } + + err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + (1 << i)); + if (err) { + printf("Authenticate img %d failed, return %d\n", + i, err); + ret = -EIO; + } + + err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, + SC_RM_PERM_NONE); + if (err) { + printf("Remove permission failed for img %d, err %d\n", + i, err); + ret = -EPERM; + } + + if (ret) + goto exit; + } + +exit: + if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0) != SC_ERR_NONE) + printf("Error: release container failed!\n"); + + return ret; +} + +static int do_authenticate(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong addr; + + if (argc < 2) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + + printf("Authenticate OS container at 0x%lx\n", addr); + + if (authenticate_os_container(addr)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static void display_life_cycle(u16 lc) +{ + printf("Lifecycle: 0x%04X, ", lc); + switch (lc) { + case 0x1: + printf("Pristine\n\n"); + break; + case 0x2: + printf("Fab\n\n"); + break; + case 0x8: + printf("Open\n\n"); + break; + case 0x20: + printf("NXP closed\n\n"); + break; + case 0x80: + printf("OEM closed\n\n"); + break; + case 0x100: + printf("Partial field return\n\n"); + break; + case 0x200: + printf("Full field return\n\n"); + break; + case 0x400: + printf("No return\n\n"); + break; + default: + printf("Unknown\n\n"); + break; + } +} + +#define AHAB_AUTH_CONTAINER_REQ 0x87 +#define AHAB_VERIFY_IMAGE_REQ 0x88 + +#define AHAB_NO_AUTHENTICATION_IND 0xee +#define AHAB_BAD_KEY_HASH_IND 0xfa +#define AHAB_INVALID_KEY_IND 0xf9 +#define AHAB_BAD_SIGNATURE_IND 0xf0 +#define AHAB_BAD_HASH_IND 0xf1 + +static void display_ahab_auth_event(u32 event) +{ + u8 cmd = (event >> 16) & 0xff; + u8 resp_ind = (event >> 8) & 0xff; + + switch (cmd) { + case AHAB_AUTH_CONTAINER_REQ: + printf("\tCMD = AHAB_AUTH_CONTAINER_REQ (0x%02X)\n", cmd); + printf("\tIND = "); + break; + case AHAB_VERIFY_IMAGE_REQ: + printf("\tCMD = AHAB_VERIFY_IMAGE_REQ (0x%02X)\n", cmd); + printf("\tIND = "); + break; + default: + return; + } + + switch (resp_ind) { + case AHAB_NO_AUTHENTICATION_IND: + printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_KEY_HASH_IND: + printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_INVALID_KEY_IND: + printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_SIGNATURE_IND: + printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_HASH_IND: + printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind); + break; + default: + printf("Unknown Indicator (0x%02X)\n\n", resp_ind); + break; + } +} + +static int do_ahab_status(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int err; + u8 idx = 0U; + u32 event; + u16 lc; + + err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); + if (err != SC_ERR_NONE) { + printf("Error in get lifecycle\n"); + return -EIO; + } + + display_life_cycle(lc); + + err = sc_seco_get_event(-1, idx, &event); + while (err == SC_ERR_NONE) { + printf("SECO Event[%u] = 0x%08X\n", idx, event); + display_ahab_auth_event(event); + + idx++; + err = sc_seco_get_event(-1, idx, &event); + } + + if (idx == 0) + printf("No SECO Events Found!\n\n"); + + return 0; +} + +static int confirm_close(void) +{ + puts("Warning: Please ensure your sample is in NXP closed state, " + "OEM SRK hash has been fused, \n" + " and you are able to boot a signed image successfully " + "without any SECO events reported.\n" + " If not, your sample will be unrecoverable.\n" + "\nReally perform this operation? <y/N>\n"); + + if (confirm_yesno()) + return 1; + + puts("Ahab close aborted\n"); + return 0; +} + +static int do_ahab_close(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int err; + u16 lc; + + if (!confirm_close()) + return -EACCES; + + err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); + if (err != SC_ERR_NONE) { + printf("Error in get lifecycle\n"); + return -EIO; + } + + if (lc != 0x20) { + puts("Current lifecycle is NOT NXP closed, can't move to OEM closed\n"); + display_life_cycle(lc); + return -EPERM; + } + + err = sc_seco_forward_lifecycle(-1, 16); + if (err != SC_ERR_NONE) { + printf("Error in forward lifecycle to OEM closed\n"); + return -EIO; + } + + printf("Change to OEM closed successfully\n"); + + return 0; +} + +U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, + "autenticate OS container via AHAB", + "addr\n" + "addr - OS container hex address\n" +); + +U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, + "display AHAB lifecycle and events from seco", + "" +); + +U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, + "Change AHAB lifecycle to OEM closed", + "" +); diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c index fe73e29eee..00fe4670bb 100644 --- a/arch/arm/mach-imx/imx8/misc.c +++ b/arch/arm/mach-imx/imx8/misc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include <common.h> #include <asm/arch/sci/sci.h> +#include <asm/mach-imx/sys_proto.h> int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) { @@ -25,9 +26,14 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) return 0; } +#define FSL_SIP_BUILDINFO 0xC2000003 +#define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 + void build_info(void) { + u32 seco_build = 0, seco_commit = 0; u32 sc_build = 0, sc_commit = 0; + ulong atf_commit = 0; /* Get SCFW build and commit id */ sc_misc_build_info(-1, &sc_build, &sc_commit); @@ -35,5 +41,23 @@ void build_info(void) printf("SCFW does not support build info\n"); sc_commit = 0; /* Display 0 if build info not supported */ } - printf("Build: SCFW %x\n", sc_commit); + + /* Get SECO FW build and commit id */ + sc_seco_build_info(-1, &seco_build, &seco_commit); + if (!seco_build) { + debug("SECO FW does not support build info\n"); + /* Display 0 when the build info is not supported */ + seco_commit = 0; + } + + /* Get ARM Trusted Firmware commit id */ + atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, + FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + if (atf_commit == 0xffffffff) { + debug("ATF does not support build info\n"); + atf_commit = 0x30; /* Display 0 */ + } + + printf("Build: SCFW %08x, SECO-FW %08x, ATF %s\n", + sc_commit, seco_commit, (char *)&atf_commit); } diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c index 32f78bdddf..b57e68e412 100644 --- a/arch/arm/mach-imx/imx8/parse-container.c +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -7,6 +7,67 @@ #include <errno.h> #include <spl.h> #include <asm/arch/image.h> +#include <asm/arch/sci/sci.h> + +#define SEC_SECURE_RAM_BASE 0x31800000UL +#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) +#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE 0x60000000UL + +#define SECO_PT 2U + +#ifdef CONFIG_AHAB_BOOT +static int authenticate_image(struct boot_img_t *img, int image_index) +{ + sc_faddr_t start, end; + sc_rm_mr_t mr; + int err; + int ret = 0; + + debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n", + image_index, img->dst, img->offset, img->size); + + /* Find the memreg and set permission for seco pt */ + err = sc_rm_find_memreg(-1, &mr, + img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), + ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE)); + + if (err) { + printf("can't find memreg for image: %d, err %d\n", + image_index, err); + return -ENOMEM; + } + + err = sc_rm_get_memreg_info(-1, mr, &start, &end); + if (!err) + debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_FULL); + if (err) { + printf("set permission failed for img %d, error %d\n", + image_index, err); + return -EPERM; + } + + err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + 1 << image_index); + if (err) { + printf("authenticate img %d failed, return %d\n", + image_index, err); + ret = -EIO; + } + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_NONE); + if (err) { + printf("remove permission failed for img %d, error %d\n", + image_index, err); + ret = -EPERM; + } + + return ret; +} +#endif static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, struct spl_load_info *info, @@ -45,6 +106,13 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, return NULL; } +#ifdef CONFIG_AHAB_BOOT + if (authenticate_image(&images[image_index], image_index)) { + printf("Failed to authenticate image %d\n", image_index); + return NULL; + } +#endif + return &images[image_index]; } @@ -54,7 +122,7 @@ static int read_auth_container(struct spl_image_info *spl_image, struct container_hdr *container = NULL; u16 length; u32 sectors; - int i, size; + int i, size, ret = 0; size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len); sectors = size / info->bl_len; @@ -96,13 +164,27 @@ static int read_auth_container(struct spl_image_info *spl_image, return -EIO; } +#ifdef CONFIG_AHAB_BOOT + memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + ret = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + if (ret) { + printf("authenticate container hdr failed, return %d\n", ret); + return ret; + } +#endif + for (i = 0; i < container->num_images; i++) { struct boot_img_t *image = read_auth_image(spl_image, info, container, i, sector); - if (!image) - return -EINVAL; + if (!image) { + ret = -EINVAL; + goto end_auth; + } if (i == 0) { spl_image->load_addr = image->dst; @@ -110,7 +192,12 @@ static int read_auth_container(struct spl_image_info *spl_image, } } - return 0; +end_auth: +#ifdef CONFIG_AHAB_BOOT + if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0)) + printf("Error: release container failed!\n"); +#endif + return ret; } int spl_load_imx_container(struct spl_image_info *spl_image, diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index feecdb50f6..2db5bde211 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -393,6 +393,15 @@ void init_usb_clk(void) } } +void init_nand_clk(void) +{ + clock_enable(CCGR_RAWNAND, 0); + clock_set_target_val(NAND_CLK_ROOT, + CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(3) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4)); + clock_enable(CCGR_RAWNAND, 1); +} + void init_uart_clk(u32 index) { /* Set uart clock root 25M OSC */ @@ -804,6 +813,13 @@ int clock_init(void) init_wdog_clk(); clock_enable(CCGR_TSENSOR, 1); + clock_enable(CCGR_OCOTP, 1); + + /* config GIC ROOT to sys_pll2_200m */ + clock_enable(CCGR_GIC, 0); + clock_set_target_val(GIC_CLK_ROOT, + CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_GIC, 1); return 0; } diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index aeca82cdbf..a924af431c 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -202,14 +202,21 @@ u32 get_cpu_rev(void) } else { if (reg == CHIP_REV_1_0) { /* - * For B0 chip, the DIGPROG is not updated, still TO1.0. - * we have to check ROM version further + * For B0 chip, the DIGPROG is not updated, + * it is still TO1.0. we have to check ROM + * version or OCOTP_READ_FUSE_DATA. + * 0xff0055aa is magic number for B1. */ - rom_version = readl((void __iomem *)ROM_VERSION_A0); - if (rom_version != CHIP_REV_1_0) { - rom_version = readl((void __iomem *)ROM_VERSION_B0); - if (rom_version >= CHIP_REV_2_0) - reg = CHIP_REV_2_0; + if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) { + reg = CHIP_REV_2_1; + } else { + rom_version = + readl((void __iomem *)ROM_VERSION_A0); + if (rom_version != CHIP_REV_1_0) { + rom_version = readl((void __iomem *)ROM_VERSION_B0); + if (rom_version == CHIP_REV_2_0) + reg = CHIP_REV_2_0; + } } } } diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index 18d7e6819c..3d9422d5a2 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -26,7 +26,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) /* Enable M4 */ #ifdef CONFIG_IMX8M - call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0); + call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0); #else clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); @@ -38,7 +38,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) int arch_auxiliary_core_check_up(u32 core_id) { #ifdef CONFIG_IMX8M - return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0); + return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0); #else unsigned int val; diff --git a/arch/arm/mach-imx/init.c b/arch/arm/mach-imx/init.c index b8d8d12372..693b724429 100644 --- a/arch/arm/mach-imx/init.c +++ b/arch/arm/mach-imx/init.c @@ -108,9 +108,9 @@ void boot_mode_apply(unsigned cfg_val) writel(cfg_val, &psrc->gpr9); reg = readl(&psrc->gpr10); if (cfg_val) - reg |= 1 << 28; + reg |= IMX6_SRC_GPR10_BMODE; else - reg &= ~(1 << 28); + reg &= ~IMX6_SRC_GPR10_BMODE; writel(reg, &psrc->gpr10); } #endif @@ -118,7 +118,7 @@ void boot_mode_apply(unsigned cfg_val) #if defined(CONFIG_MX6) u32 imx6_src_get_boot_mode(void) { - if (imx6_is_bmode_from_gpr9()) + if (readl(&src_base->gpr10) & IMX6_SRC_GPR10_BMODE) return readl(&src_base->gpr9); else return readl(&src_base->sbmr1); diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index 00e3c486bc..607210520f 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -232,6 +232,13 @@ config TARGET_MCCMON6 bool "mccmon6" select MX6QDL select SUPPORT_SPL + select DM + select DM_GPIO + select DM_ETH + select DM_SERIAL + select DM_I2C + select DM_SPI + imply CMD_DM config TARGET_MX6CUBOXI bool "Solid-run mx6 boards" @@ -589,6 +596,24 @@ config TARGET_ZC5601 select SUPPORT_SPL imply CMD_DM +config TARGET_BRPPT2 + bool "brppt2" + select BOARD_LATE_INIT + select MX6QDL + select OF_CONTROL + select SPL_OF_LIBFDT + select DM + select DM_ETH + select DM_GPIO + select DM_I2C + select DM_MMC + select SUPPORT_SPL + select SPL_DM if SPL + select SPL_OF_CONTROL if SPL + help + Support + B&R BRPPT2 platform + based on Freescale's iMX6 SoC endchoice config SYS_SOC @@ -646,5 +671,6 @@ source "board/udoo/Kconfig" source "board/udoo/neo/Kconfig" source "board/wandboard/Kconfig" source "board/warp/Kconfig" +source "board/BuR/brppt2/Kconfig" endif diff --git a/arch/arm/mach-imx/mx6/clock.c b/arch/arm/mach-imx/mx6/clock.c index 7763c79e1c..6a9e673ca2 100644 --- a/arch/arm/mach-imx/mx6/clock.c +++ b/arch/arm/mach-imx/mx6/clock.c @@ -1279,16 +1279,26 @@ unsigned int mxc_get_clock(enum mxc_clock clk) void enable_ipu_clock(void) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - reg = readl(&mxc_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK; - writel(reg, &mxc_ccm->CCGR3); + + setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_MASK); if (is_mx6dqp()) { setbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK); setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK); } } + +void disable_ipu_clock(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + clrbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_MASK); + + if (is_mx6dqp()) { + clrbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK); + clrbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK); + } +} #endif #ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/mach-imx/mx6/opos6ul.c b/arch/arm/mach-imx/mx6/opos6ul.c index 3ab9a3f022..0c640e2e33 100644 --- a/arch/arm/mach-imx/mx6/opos6ul.c +++ b/arch/arm/mach-imx/mx6/opos6ul.c @@ -6,11 +6,7 @@ #include <asm/arch/clock.h> #include <asm/arch/crm_regs.h> #include <asm/arch/imx-regs.h> -#include <asm/arch/iomux.h> -#include <asm/arch/mx6-pins.h> #include <asm/arch/sys_proto.h> -#include <asm/gpio.h> -#include <asm/mach-imx/iomux-v3.h> #include <asm/io.h> #include <common.h> #include <env.h> @@ -20,43 +16,6 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_FEC_MXC #include <miiphy.h> -#define MDIO_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PU ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PD ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_CLK_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST \ -) - -static iomux_v3_cfg_t const fec1_pads[] = { - MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Int */ - MX6_PAD_NAND_DQS__GPIO4_IO16 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Reset */ - MX6_PAD_NAND_DATA00__GPIO4_IO02 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), -}; - int board_phy_config(struct phy_device *phydev) { phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190); @@ -67,43 +26,16 @@ int board_phy_config(struct phy_device *phydev) return 0; } -int board_eth_init(bd_t *bis) +static int setup_fec(void) { struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; - struct gpio_desc rst; - int ret; /* Use 50M anatop loopback REF_CLK1 for ENET1, * clear gpr1[13], set gpr1[17] */ clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK); - ret = enable_fec_anatop_clock(0, ENET_50MHZ); - if (ret) - return ret; - - enable_enet_clk(1); - - imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); - - ret = dm_gpio_lookup_name("GPIO4_2", &rst); - if (ret) { - printf("Cannot get GPIO4_2\n"); - return ret; - } - - ret = dm_gpio_request(&rst, "phy-rst"); - if (ret) { - printf("Cannot request GPIO4_2\n"); - return ret; - } - - dm_gpio_set_dir_flags(&rst, GPIOD_IS_OUT); - dm_gpio_set_value(&rst, 0); - udelay(1000); - dm_gpio_set_value(&rst, 1); - - return fecmxc_initialize(bis); + return enable_fec_anatop_clock(0, ENET_50MHZ); } #endif /* CONFIG_FEC_MXC */ @@ -112,6 +44,10 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + return 0; } diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c index 968e7cf309..fca520c671 100644 --- a/arch/arm/mach-imx/sip.c +++ b/arch/arm/mach-imx/sip.c @@ -7,7 +7,8 @@ #include <asm/arch/sys_proto.h> unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2) + unsigned long reg1, unsigned long reg2, + unsigned long reg3) { struct pt_regs regs; @@ -15,6 +16,7 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0, regs.regs[1] = reg0; regs.regs[2] = reg1; regs.regs[3] = reg2; + regs.regs[4] = reg3; smc_call(®s); diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index f025c4b301..5cc74b6f9b 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -189,6 +189,34 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) /* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */ u32 spl_boot_mode(const u32 boot_device) { +#if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) + switch (get_boot_device()) { + /* for MMC return either RAW or FAT mode */ + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: +#if defined(CONFIG_SPL_FAT_SUPPORT) + return MMCSD_MODE_FS; +#else + return MMCSD_MODE_RAW; +#endif + break; + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: +#if defined(CONFIG_SPL_FAT_SUPPORT) + return MMCSD_MODE_FS; +#elif defined(CONFIG_SUPPORT_EMMC_BOOT) + return MMCSD_MODE_EMMCBOOT; +#else + return MMCSD_MODE_RAW; +#endif + break; + default: + puts("spl: ERROR: unsupported device\n"); + hang(); + } +#else /* * When CONFIG_SPL_FORCE_MMC_BOOT is defined the 'boot_device' is used * unconditionally to decide about device to use for booting. @@ -217,6 +245,7 @@ u32 spl_boot_mode(const u32 boot_device) puts("spl: ERROR: unsupported device\n"); hang(); } +#endif } #endif |