From fb8cac936615e6e75237ce95ccaa09d8b109cae3 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 3 Jan 2018 16:11:56 +0100 Subject: mx6: Support SKS-Kinkel sksimx6 Board Board has 1GB RAM and boots from SD Card U-Boot SPL 2018.01-rc3-00005-ga1898b8 (Jan 02 2018 - 13:48:54) BT_FUSE_SEL already fused, will do nothing Trying to boot from MMC1 U-Boot 2018.01-rc3-00005-ga1898b8 (Jan 02 2018 - 13:48:54 +0100) CPU: Freescale i.MX6DL rev1.2 996 MHz (running at 792 MHz) CPU: Commercial temperature grade (0C to 95C) at 40C Reset cause: POR I2C: ready DRAM: 1 GiB MMC: FSL_SDHC: 0 In: serial Out: serial Err: serial Net: FEC [PRIME] Signed-off-by: Stefano Babic Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/mx6/Kconfig | 5 + board/sks-kinkel/sksimx6/Kconfig | 11 + board/sks-kinkel/sksimx6/MAINTAINERS | 6 + board/sks-kinkel/sksimx6/Makefile | 3 + board/sks-kinkel/sksimx6/sksimx6.c | 426 +++++++++++++++++++++++++++++++++++ configs/sksimx6_defconfig | 47 ++++ include/configs/sksimx6.h | 101 +++++++++ 7 files changed, 599 insertions(+) create mode 100644 board/sks-kinkel/sksimx6/Kconfig create mode 100644 board/sks-kinkel/sksimx6/MAINTAINERS create mode 100644 board/sks-kinkel/sksimx6/Makefile create mode 100644 board/sks-kinkel/sksimx6/sksimx6.c create mode 100644 configs/sksimx6_defconfig create mode 100644 include/configs/sksimx6.h diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index 567a6a6bf5..c11c02c87b 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -377,6 +377,10 @@ config TARGET_PFLA02 config TARGET_SECOMX6 bool "secomx6 boards" +config TARGET_SKSIMX6 + bool "sks-imx6" + select SUPPORT_SPL + config TARGET_TBS2910 bool "TBS2910 Matrix ARM mini PC" @@ -482,6 +486,7 @@ source "board/liebherr/display5/Kconfig" source "board/liebherr/mccmon6/Kconfig" source "board/logicpd/imx6/Kconfig" source "board/seco/Kconfig" +source "board/sks-kinkel/sksimx6/Kconfig" source "board/solidrun/mx6cuboxi/Kconfig" source "board/technexion/pico-imx6ul/Kconfig" source "board/tbs/tbs2910/Kconfig" diff --git a/board/sks-kinkel/sksimx6/Kconfig b/board/sks-kinkel/sksimx6/Kconfig new file mode 100644 index 0000000000..3efdf9d8b2 --- /dev/null +++ b/board/sks-kinkel/sksimx6/Kconfig @@ -0,0 +1,11 @@ +if TARGET_SKSIMX6 + +config SYS_BOARD + default "sksimx6" + +config SYS_VENDOR + default "sks-kinkel" + +config SYS_CONFIG_NAME + default "sksimx6" +endif diff --git a/board/sks-kinkel/sksimx6/MAINTAINERS b/board/sks-kinkel/sksimx6/MAINTAINERS new file mode 100644 index 0000000000..c1527bfa5f --- /dev/null +++ b/board/sks-kinkel/sksimx6/MAINTAINERS @@ -0,0 +1,6 @@ +SKS-Kinkel sksimx6 +M: Stefano Babic +S: Maintained +F: board/sks-kinkel/sksimx6/ +F: include/configs/sksimx6.h +F: configs/sksimx6_defconfig diff --git a/board/sks-kinkel/sksimx6/Makefile b/board/sks-kinkel/sksimx6/Makefile new file mode 100644 index 0000000000..676a007744 --- /dev/null +++ b/board/sks-kinkel/sksimx6/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +obj-y := sksimx6.o diff --git a/board/sks-kinkel/sksimx6/sksimx6.c b/board/sks-kinkel/sksimx6/sksimx6.c new file mode 100644 index 0000000000..d50d4086f6 --- /dev/null +++ b/board/sks-kinkel/sksimx6/sksimx6.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2016 Stefano Babic + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +static iomux_v3_cfg_t const uart1_pads[] = { + IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const gpios_pads[] = { + IOMUX_PADS(PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),/* CD */ +}; + +static iomux_v3_cfg_t const enet_pads[] = { + IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | + MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | + MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | + MUX_PAD_CTRL(ENET_PAD_CTRL)), + IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +iomux_v3_cfg_t const enet_pads1[] = { + /* pin 35 - 1 (PHY_AD2) on reset */ + IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 32 - 1 - (MODE0) all */ + IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 31 - 1 - (MODE1) all */ + IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 28 - 1 - (MODE2) all */ + IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 27 - 1 - (MODE3) all */ + IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */ + IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)), + /* pin 42 PHY nRST */ + IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static int mx6_rgmii_rework(struct phy_device *phydev) +{ + + /* min rx data delay */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, + 0x0); + /* min tx data delay */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, + 0x0); + /* max rx/tx clock delay, min rx/tx control */ + ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, + 0xf0f0); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + mx6_rgmii_rework(phydev); + + if (phydev->drv->config) + return phydev->drv->config(phydev); + + return 0; +} + +#define ENET_NRST IMX_GPIO_NR(1, 25) + +void setup_iomux_enet(void) +{ + SETUP_IOMUX_PADS(enet_pads); + +} + +int board_eth_init(bd_t *bis) +{ + uint32_t base = IMX_FEC_BASE; + struct mii_dev *bus = NULL; + struct phy_device *phydev = NULL; + int ret; + + setup_iomux_enet(); + + bus = fec_get_miibus(base, -1); + if (!bus) + return -EINVAL; + /* scan phy */ + phydev = phy_find_by_mask(bus, (0xf << CONFIG_FEC_MXC_PHYADDR), + PHY_INTERFACE_MODE_RGMII); + + if (!phydev) { + ret = -EINVAL; + goto free_bus; + } + ret = fec_probe(bis, -1, base, bus, phydev); + if (ret) + goto free_phydev; + + return 0; + +free_phydev: + free(phydev); +free_bus: + free(bus); + return ret; +} + +int board_early_init_f(void) +{ + SETUP_IOMUX_PADS(uart1_pads); + + return 0; +} + +int board_init(void) +{ + /* Address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + /* Take in reset the ATMega processor */ + SETUP_IOMUX_PADS(gpios_pads); + gpio_direction_output(IMX_GPIO_NR(5, 4), 0); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} + +struct fsl_esdhc_cfg usdhc_cfg[1] = { + {USDHC2_BASE_ADDR, 0}, +}; + +#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 0) +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC2_BASE_ADDR) + ret = 1; + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + SETUP_IOMUX_PADS(usdhc2_pads); + gpio_direction_input(USDHC2_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + usdhc_cfg[0].max_bus_width = 4; + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]); + if (ret) { + printf("Warning: failed to initialize mmc dev \n"); + return ret; + } + + return 0; +} + +#if defined(CONFIG_SPL_BUILD) +#include + +/* + * Driving strength: + * 0x30 == 40 Ohm + * 0x28 == 48 Ohm + */ +#define IMX6SDL_DRIVE_STRENGTH 0x230 + + +/* configure MX6SOLO/DUALLITE mmdc DDR io registers */ +struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = { + .dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH, + .dram_cas = IMX6SDL_DRIVE_STRENGTH, + .dram_ras = IMX6SDL_DRIVE_STRENGTH, + .dram_reset = IMX6SDL_DRIVE_STRENGTH, + .dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdba2 = 0x00000000, + .dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH, + .dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm0 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm1 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm2 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm3 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm4 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm5 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm6 = IMX6SDL_DRIVE_STRENGTH, + .dram_dqm7 = IMX6SDL_DRIVE_STRENGTH, +}; + +/* configure MX6SOLO/DUALLITE mmdc GRP io registers */ +struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + .grp_ddrpke = 0x00000000, + .grp_addds = IMX6SDL_DRIVE_STRENGTH, + .grp_ctlds = IMX6SDL_DRIVE_STRENGTH, + .grp_ddrmode = 0x00020000, + .grp_b0ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b1ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b2ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b3ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b4ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b5ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b6ds = IMX6SDL_DRIVE_STRENGTH, + .grp_b7ds = IMX6SDL_DRIVE_STRENGTH, +}; + +/* MT41K128M16JT-125 */ +static struct mx6_ddr3_cfg mt41k128m16jt_125 = { + /* quad = 1066, duallite = 800 */ + .mem_speed = 1066, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, + .SRT = 0, +}; + +static struct mx6_mmdc_calibration mx6dl_1g_mmdc_calib = { + .p0_mpwldectrl0 = 0x0043004E, + .p0_mpwldectrl1 = 0x003D003F, + .p1_mpwldectrl0 = 0x00230021, + .p1_mpwldectrl1 = 0x0028003E, + .p0_mpdgctrl0 = 0x42580250, + .p0_mpdgctrl1 = 0x0238023C, + .p1_mpdgctrl0 = 0x422C0238, + .p1_mpdgctrl1 = 0x02180228, + .p0_mprddlctl = 0x44464A46, + .p1_mprddlctl = 0x44464A42, + .p0_mpwrdlctl = 0x36343236, + .p1_mpwrdlctl = 0x36343230, +}; + +/* DDR 64bit 1GB */ +static struct mx6_ddr_sysinfo mem_qdl = { + .dsize = 2, + .cs1_mirror = 0, + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, + .ncs = 1, + .bi_on = 1, + .rtt_nom = 1, + .rtt_wr = 1, + .ralat = 5, + .walat = 0, + .mif3_mode = 3, + .rst_to_cke = 0x23, + .sde_to_rst = 0x10, + .refsel = 1, /* Refresh cycles at 32KHz */ + .refr = 7, /* 8 refresh commands per refresh cycle */ +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* set the default clock gate to save power */ + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFC000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0xFFFFFFFF, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); +} + +static void spl_dram_init(void) +{ + if (is_cpu_type(MXC_CPU_MX6DL)) { + mt41k128m16jt_125.mem_speed = 800; + mem_qdl.rtt_nom = 1; + mem_qdl.rtt_wr = 1; + + mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs); + mx6_dram_cfg(&mem_qdl, &mx6dl_1g_mmdc_calib, &mt41k128m16jt_125); + } else { + printf("Wrong CPU for this board\n"); + return; + } + + udelay(100); + +#ifdef CONFIG_MX6_DDRCAL + + /* Perform DDR DRAM calibration */ + mmdc_do_write_level_calibration(&mem_qdl); + mmdc_do_dqs_calibration(&mem_qdl); +#endif +} + +static void check_bootcfg(void) +{ + u32 val5, val6; + + fuse_sense(0, 5, &val5); + fuse_sense(0, 6, &val6); + /* Check if boot from MMC */ + if (val6 & 0x10) { + puts("BT_FUSE_SEL already fused, will do nothing\n"); + return; + } + fuse_prog(0, 5, 0x00000840); + /* BT_FUSE_SEL */ + fuse_prog(0, 6, 0x00000010); + + do_reset(NULL, 0, 0, NULL); +} + +void board_init_f(ulong dummy) +{ + ccgr_init(); + + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + gpr_init(); + + /* iomux */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* DDR initialization */ + spl_dram_init(); + + /* Set fuses for new boards and reboot if not set */ + check_bootcfg(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} +#endif diff --git a/configs/sksimx6_defconfig b/configs/sksimx6_defconfig new file mode 100644 index 0000000000..454399681e --- /dev/null +++ b/configs/sksimx6_defconfig @@ -0,0 +1,47 @@ +CONFIG_ARM=y +CONFIG_ARCH_MX6=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_MX6_DDRCAL=y +CONFIG_TARGET_SKSIMX6=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6QDL" +CONFIG_BOOTDELAY=1 +CONFIG_SILENT_CONSOLE=y +CONFIG_SILENT_U_BOOT_ONLY=y +CONFIG_VERSION_VARIABLE=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SPL=y +CONFIG_SPL_EXT_SUPPORT=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_DM=y +CONFIG_PHYLIB=y +CONFIG_PHY_MICREL=y +CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_PHY_MICREL_KSZ8XXX=y +CONFIG_NETDEVICES=y +CONFIG_FEC_MXC=y +CONFIG_DM_THERMAL=y +CONFIG_OF_LIBFDT=y diff --git a/include/configs/sksimx6.h b/include/configs/sksimx6.h new file mode 100644 index 0000000000..c635e9f1b5 --- /dev/null +++ b/include/configs/sksimx6.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) Stefano Babic + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#ifndef __SKSIMX6_CONFIG_H +#define __SKSIMX6_CONFIG_H + +#include + +#include "mx6_common.h" +#include "imx6_spl.h" + +/* Thermal */ +#define CONFIG_IMX_THERMAL + +/* Serial */ +#define CONFIG_MXC_UART +#define CONFIG_MXC_UART_BASE UART1_BASE + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (8 * SZ_1M) + +/* Ethernet */ +#define IMX_FEC_BASE ENET_BASE_ADDR +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_ETHPRIME "FEC" +#define CONFIG_FEC_MXC_PHYADDR 0x01 + +#define CONFIG_MII +#define CONFIG_PHY_MICREL_KSZ9021 + +/* I2C Configs */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC +#define CONFIG_SYS_I2C_MXC_I2C2 +#define CONFIG_SYS_I2C_SPEED 100000 + +/* Filesystem support */ + +/* Physical Memory Map */ +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +/* MMC Configs */ +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 +#define CONFIG_SYS_FSL_USDHC_NUM 1 + +/* Environment organization */ +#define CONFIG_ENV_SIZE (16 * 1024) +#define CONFIG_ENV_OFFSET (6 * 64 * 1024) +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + \ + CONFIG_ENV_SIZE) +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE + +/* Default environment */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "addcons=setenv bootargs ${bootargs} " \ + "console=${console},${baudrate}\0" \ + "addip=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:" \ + "${netmask}:${hostname}:${netdev}:off\0" \ + "addmisc=setenv bootargs ${bootargs} ${miscargs}\0" \ + "bootcmd=run mmcboot\0" \ + "bootfile=uImage\0" \ + "bootimage=uImage\0" \ + "console=ttymxc0\0" \ + "fdt_addr_r=0x18000000\0" \ + "fdt_file=imx6dl-sks-cts.dtb\0" \ + "fdt_high=0xffffffff\0" \ + "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ + "miscargs=quiet\0" \ + "mmcargs=setenv bootargs root=${mmcroot} rw rootwait\0" \ + "mmcboot=if run mmcload;then " \ + "run mmcargs addcons addmisc;" \ + "bootm;fi\0" \ + "mmcload=mmc rescan;" \ + "load mmc 0:${mmcpart} ${kernel_addr_r} boot/fitImage\0"\ + "mmcpart=1\0" \ + "mmcroot=/dev/mmcblk0p1\0" \ + "net_nfs=tftp ${kernel_addr_r} ${board_name}/${bootfile};" \ + "tftp ${fdt_addr_r} ${board_name}/${fdt_file};" \ + "run nfsargs addip addcons addmisc;" \ + "bootm ${kernel_addr_r} - ${fdt_addr_r}\0" \ + "nfsargs=setenv bootargs root=/dev/nfs " \ + "nfsroot=${serverip}:${nfsroot},v3 panic=1\0" + +#endif -- cgit From 8df42bee0e728707ef4f7e7d2b12b015a4a95200 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 15:51:20 +0800 Subject: misc: mxc_ocotp: check fuse word before programming on i.MX7ULP On i.MX7ULP, the fuse words (except bank 0 and 1) only supports to write once, because they use ECC mode. Multiple writes may damage the ECC value and cause a wrong fuse value decoded when reading. This patch adds a checking before the fuse word programming, only can write when the word value is 0. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/misc/mxc_ocotp.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c index 8986bb4ad0..18a2730909 100644 --- a/drivers/misc/mxc_ocotp.c +++ b/drivers/misc/mxc_ocotp.c @@ -342,6 +342,23 @@ int fuse_sense(u32 bank, u32 word, u32 *val) static int prepare_write(struct ocotp_regs **regs, u32 bank, u32 word, const char *caller) { +#ifdef CONFIG_MX7ULP + u32 val; + int ret; + + /* Only bank 0 and 1 are redundancy mode, others are ECC mode */ + if (bank != 0 && bank != 1) { + ret = fuse_sense(bank, word, &val); + if (ret) + return ret; + + if (val != 0) { + printf("mxc_ocotp: The word has been programmed, no more write\n"); + return -EPERM; + } + } +#endif + return prepare_access(regs, bank, word, true, caller); } -- cgit From 220e88787a40c2e6ff3d120477f7748060861a42 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:04 +0800 Subject: ARM: imx: Introduce dts for i.MX6SX-SDB Introduce dts from Kernel commit commit 71ee203389f7cb1c("Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi") Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6sx-sdb.dts | 138 ++++++++++ arch/arm/dts/imx6sx-sdb.dtsi | 612 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 751 insertions(+) create mode 100644 arch/arm/dts/imx6sx-sdb.dts create mode 100644 arch/arm/dts/imx6sx-sdb.dtsi diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index bbc4f476d0..19100c95f4 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -384,6 +384,7 @@ dtb-$(CONFIG_MX6) += imx6ull-14x14-evk.dtb \ imx6q-icore-rqs.dtb \ imx6q-logicpd.dtb \ imx6sx-sabreauto.dtb \ + imx6sx-sdb.dtb \ imx6ul-geam-kit.dtb \ imx6ul-isiot-emmc.dtb \ imx6ul-isiot-mmc.dtb \ diff --git a/arch/arm/dts/imx6sx-sdb.dts b/arch/arm/dts/imx6sx-sdb.dts new file mode 100644 index 0000000000..6dd9bebfe0 --- /dev/null +++ b/arch/arm/dts/imx6sx-sdb.dts @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "imx6sx-sdb.dtsi" + +/ { + model = "Freescale i.MX6 SoloX SDB RevB Board"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic: pfuze100@8 { + compatible = "fsl,pfuze200"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3b_reg: sw3b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + regulator-always-on; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&qspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qspi2>; + status = "okay"; + + flash0: n25q256a@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + reg = <0>; + }; + + flash1: n25q256a@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + reg = <1>; + }; +}; + +®_arm { + vin-supply = <&sw1a_reg>; +}; + +®_soc { + vin-supply = <&sw1a_reg>; +}; diff --git a/arch/arm/dts/imx6sx-sdb.dtsi b/arch/arm/dts/imx6sx-sdb.dtsi new file mode 100644 index 0000000000..da815527a7 --- /dev/null +++ b/arch/arm/dts/imx6sx-sdb.dtsi @@ -0,0 +1,612 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/dts-v1/; + +#include +#include +#include "imx6sx.dtsi" + +/ { + model = "Freescale i.MX6 SoloX SDB Board"; + compatible = "fsl,imx6sx-sdb", "fsl,imx6sx"; + + chosen { + stdout-path = &uart1; + }; + + memory { + reg = <0x80000000 0x40000000>; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&pwm3 0 5000000>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + volume-up { + label = "Volume Up"; + gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vcc_sd3: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_vcc_sd3>; + regulator-name = "VCC_SD3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + gpio = <&gpio2 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg1_vbus: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_otg1>; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg2_vbus: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_otg2>; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_psu_5v: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "PSU-5V0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_lcd_3v3: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "lcd-3v3"; + gpio = <&gpio3 27 0>; + enable-active-high; + }; + + reg_peri_3v3: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_peri_3v3>; + regulator-name = "peri_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio4 16 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_enet_3v3: regulator@6 { + compatible = "regulator-fixed"; + reg = <6>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet_3v3>; + regulator-name = "enet_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio2 6 GPIO_ACTIVE_LOW>; + }; + }; + + sound { + compatible = "fsl,imx6sx-sdb-wm8962", "fsl,imx-audio-wm8962"; + model = "wm8962-audio"; + ssi-controller = <&ssi2>; + audio-codec = <&codec>; + audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "Ext Spk", "SPKOUTL", + "Ext Spk", "SPKOUTR", + "AMIC", "MICBIAS", + "IN3R", "AMIC"; + mux-int-port = <2>; + mux-ext-port = <6>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + phy-supply = <®_enet_3v3>; + phy-mode = "rgmii"; + phy-handle = <ðphy1>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy1: ethernet-phy@1 { + reg = <1>; + }; + + ethphy2: ethernet-phy@2 { + reg = <2>; + }; + }; +}; + +&fec2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet2>; + phy-mode = "rgmii"; + phy-handle = <ðphy2>; + status = "okay"; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&i2c4 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + codec: wm8962@1a { + compatible = "wlf,wm8962"; + reg = <0x1a>; + clocks = <&clks IMX6SX_CLK_AUDIO>; + DCVDD-supply = <&vgen4_reg>; + DBVDD-supply = <&vgen4_reg>; + AVDD-supply = <&vgen4_reg>; + CPVDD-supply = <&vgen4_reg>; + MICVDD-supply = <&vgen3_reg>; + PLLVDD-supply = <&vgen4_reg>; + SPKVDD1-supply = <®_psu_5v>; + SPKVDD2-supply = <®_psu_5v>; + }; +}; + +&lcdif1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcd>; + lcd-supply = <®_lcd_3v3>; + display = <&display0>; + status = "okay"; + + display0: display0 { + bits-per-pixel = <16>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33500000>; + hactive = <800>; + vactive = <480>; + hback-porch = <89>; + hfront-porch = <164>; + vback-porch = <23>; + vfront-porch = <10>; + hsync-len = <10>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "okay"; +}; + +&snvs_poweroff { + status = "okay"; +}; + +&sai1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai1>; + status = "disabled"; +}; + +&ssi2 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart5 { /* for bluetooth */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + uart-has-rtscts; + status = "okay"; +}; + +&usbotg1 { + vbus-supply = <®_usb_otg1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_otg1_id>; + status = "okay"; +}; + +&usbotg2 { + vbus-supply = <®_usb_otg2_vbus>; + dr_mode = "host"; + status = "okay"; +}; + +&usbphy1 { + fsl,tx-d-cal = <106>; +}; + +&usbphy2 { + fsl,tx-d-cal = <106>; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + non-removable; + no-1-8-v; + keep-power-in-suspend; + wakeup-source; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + bus-width = <8>; + cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; + keep-power-in-suspend; + wakeup-source; + vmmc-supply = <&vcc_sd3>; + status = "okay"; +}; + +&usdhc4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4>; + cd-gpios = <&gpio6 21 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + imx6x-sdb { + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC 0x130b0 + MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS 0x130b0 + MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD 0x120b0 + MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD 0x130b0 + MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130b0 + >; + }; + + pinctrl_enet1: enet1grp { + fsl,pins = < + MX6SX_PAD_ENET1_MDIO__ENET1_MDIO 0xa0b1 + MX6SX_PAD_ENET1_MDC__ENET1_MDC 0xa0b1 + MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC 0xa0b1 + MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 0xa0b1 + MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 0xa0b1 + MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 0xa0b1 + MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 0xa0b1 + MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN 0xa0b1 + MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK 0x3081 + MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 0x3081 + MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 0x3081 + MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 0x3081 + MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 0x3081 + MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN 0x3081 + MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M 0x91 + >; + }; + + pinctrl_enet_3v3: enet3v3grp { + fsl,pins = < + MX6SX_PAD_ENET2_COL__GPIO2_IO_6 0x80000000 + >; + }; + + pinctrl_enet2: enet2grp { + fsl,pins = < + MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC 0xa0b9 + MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 0xa0b1 + MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 0xa0b1 + MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 0xa0b1 + MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 0xa0b1 + MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN 0xa0b1 + MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK 0x3081 + MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 0x3081 + MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 0x3081 + MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 0x3081 + MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 0x3081 + MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN 0x3081 + >; + }; + + pinctrl_gpio_keys: gpio_keysgrp { + fsl,pins = < + MX6SX_PAD_CSI_DATA04__GPIO1_IO_18 0x17059 + MX6SX_PAD_CSI_DATA05__GPIO1_IO_19 0x17059 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO01__I2C1_SDA 0x4001b8b1 + MX6SX_PAD_GPIO1_IO00__I2C1_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1 + MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1 + MX6SX_PAD_CSI_DATA06__I2C4_SCL 0x4001b8b1 + >; + }; + + pinctrl_lcd: lcdgrp { + fsl,pins = < + MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0 0x4001b0b0 + MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1 0x4001b0b0 + MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2 0x4001b0b0 + MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3 0x4001b0b0 + MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4 0x4001b0b0 + MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5 0x4001b0b0 + MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6 0x4001b0b0 + MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7 0x4001b0b0 + MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8 0x4001b0b0 + MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9 0x4001b0b0 + MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10 0x4001b0b0 + MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11 0x4001b0b0 + MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12 0x4001b0b0 + MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13 0x4001b0b0 + MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14 0x4001b0b0 + MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15 0x4001b0b0 + MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16 0x4001b0b0 + MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17 0x4001b0b0 + MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18 0x4001b0b0 + MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19 0x4001b0b0 + MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20 0x4001b0b0 + MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21 0x4001b0b0 + MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22 0x4001b0b0 + MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23 0x4001b0b0 + MX6SX_PAD_LCD1_CLK__LCDIF1_CLK 0x4001b0b0 + MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE 0x4001b0b0 + MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC 0x4001b0b0 + MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC 0x4001b0b0 + MX6SX_PAD_LCD1_RESET__GPIO3_IO_27 0x4001b0b0 + >; + }; + + pinctrl_peri_3v3: peri3v3grp { + fsl,pins = < + MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16 0x80000000 + >; + }; + + pinctrl_pwm3: pwm3grp-1 { + fsl,pins = < + MX6SX_PAD_SD1_DATA2__PWM3_OUT 0x110b0 + >; + }; + + pinctrl_qspi2: qspi2grp { + fsl,pins = < + MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0 0x70f1 + MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1 0x70f1 + MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2 0x70f1 + MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3 0x70f1 + MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK 0x70f1 + MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B 0x70f1 + MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0 0x70f1 + MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1 0x70f1 + MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2 0x70f1 + MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3 0x70f1 + MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK 0x70f1 + MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B 0x70f1 + >; + }; + + pinctrl_vcc_sd3: vccsd3grp { + fsl,pins = < + MX6SX_PAD_KEY_COL1__GPIO2_IO_11 0x17059 + >; + }; + + pinctrl_sai1: sai1grp { + fsl,pins = < + MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK 0x130b0 + MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC 0x130b0 + MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0 0x120b0 + MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0 0x130b0 + MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK 0x130b0 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO04__UART1_TX 0x1b0b1 + MX6SX_PAD_GPIO1_IO05__UART1_RX 0x1b0b1 + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX6SX_PAD_KEY_ROW3__UART5_RX 0x1b0b1 + MX6SX_PAD_KEY_COL3__UART5_TX 0x1b0b1 + MX6SX_PAD_KEY_ROW2__UART5_CTS_B 0x1b0b1 + MX6SX_PAD_KEY_COL2__UART5_RTS_B 0x1b0b1 + >; + }; + + pinctrl_usb_otg1: usbotg1grp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9 0x10b0 + >; + }; + + pinctrl_usb_otg1_id: usbotg1idgrp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID 0x17059 + >; + }; + + pinctrl_usb_otg2: usbot2ggrp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12 0x10b0 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6SX_PAD_SD2_CMD__USDHC2_CMD 0x17059 + MX6SX_PAD_SD2_CLK__USDHC2_CLK 0x10059 + MX6SX_PAD_SD2_DATA0__USDHC2_DATA0 0x17059 + MX6SX_PAD_SD2_DATA1__USDHC2_DATA1 0x17059 + MX6SX_PAD_SD2_DATA2__USDHC2_DATA2 0x17059 + MX6SX_PAD_SD2_DATA3__USDHC2_DATA3 0x17059 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x17059 + MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x10059 + MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x17059 + MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x17059 + MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x17059 + MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x17059 + MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x17059 + MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x17059 + MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x17059 + MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x17059 + MX6SX_PAD_KEY_COL0__GPIO2_IO_10 0x17059 /* CD */ + MX6SX_PAD_KEY_ROW0__GPIO2_IO_15 0x17059 /* WP */ + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp-100mhz { + fsl,pins = < + MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170b9 + MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100b9 + MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170b9 + MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170b9 + MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170b9 + MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170b9 + MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170b9 + MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170b9 + MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170b9 + MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp-200mhz { + fsl,pins = < + MX6SX_PAD_SD3_CMD__USDHC3_CMD 0x170f9 + MX6SX_PAD_SD3_CLK__USDHC3_CLK 0x100f9 + MX6SX_PAD_SD3_DATA0__USDHC3_DATA0 0x170f9 + MX6SX_PAD_SD3_DATA1__USDHC3_DATA1 0x170f9 + MX6SX_PAD_SD3_DATA2__USDHC3_DATA2 0x170f9 + MX6SX_PAD_SD3_DATA3__USDHC3_DATA3 0x170f9 + MX6SX_PAD_SD3_DATA4__USDHC3_DATA4 0x170f9 + MX6SX_PAD_SD3_DATA5__USDHC3_DATA5 0x170f9 + MX6SX_PAD_SD3_DATA6__USDHC3_DATA6 0x170f9 + MX6SX_PAD_SD3_DATA7__USDHC3_DATA7 0x170f9 + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6SX_PAD_SD4_CMD__USDHC4_CMD 0x17059 + MX6SX_PAD_SD4_CLK__USDHC4_CLK 0x10059 + MX6SX_PAD_SD4_DATA0__USDHC4_DATA0 0x17059 + MX6SX_PAD_SD4_DATA1__USDHC4_DATA1 0x17059 + MX6SX_PAD_SD4_DATA2__USDHC4_DATA2 0x17059 + MX6SX_PAD_SD4_DATA3__USDHC4_DATA3 0x17059 + MX6SX_PAD_SD4_DATA7__GPIO6_IO_21 0x17059 /* CD */ + MX6SX_PAD_SD4_DATA6__GPIO6_IO_20 0x17059 /* WP */ + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY 0x30b0 + >; + }; + }; +}; -- cgit From 83fccaf1f9356364253cd75282e3ef8352e04a7b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:05 +0800 Subject: ARM: imx: Enable dts for i.MX6SX-SDB Enable DTS and OF_CONTROL for i.MX6SX-SDB. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- configs/mx6sxsabresd_defconfig | 3 ++- configs/mx6sxsabresd_spl_defconfig | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index b707322714..9ac5236df0 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y CONFIG_TARGET_MX6SXSABRESD=y # CONFIG_CMD_BMODE is not set CONFIG_NXP_BOARD_REVISION=y +CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb" CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg" # CONFIG_CONSOLE_MUX is not set CONFIG_SYS_CONSOLE_IS_IN_ENV=y @@ -27,6 +28,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_CONTROL=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_PHYLIB=y @@ -36,4 +38,3 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_VIDEO=y -CONFIG_OF_LIBFDT=y diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig index 9ab4b2f006..6a1423bd0c 100644 --- a/configs/mx6sxsabresd_spl_defconfig +++ b/configs/mx6sxsabresd_spl_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y # CONFIG_CMD_BMODE is not set CONFIG_NXP_BOARD_REVISION=y +CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb" CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" # CONFIG_CONSOLE_MUX is not set CONFIG_SYS_CONSOLE_IS_IN_ENV=y @@ -36,6 +37,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_CONTROL=y CONFIG_SPI_FLASH=y CONFIG_PHYLIB=y CONFIG_PCI=y @@ -44,4 +46,3 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_VIDEO=y -CONFIG_OF_LIBFDT=y -- cgit From f8e450a7f61a04967d3fa74817b3abc9ec95aecd Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:06 +0800 Subject: board: freescale: common: add pfuze dm code Add pfuze dm code, this code could be enabled with CONFIG_DM_PMIC_PFUZE100. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- board/freescale/common/Makefile | 1 + board/freescale/common/pfuze.c | 79 +++++++++++++++++++++++++++++++++++++++++ board/freescale/common/pfuze.h | 5 +++ 3 files changed, 85 insertions(+) diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 1c53fb605b..e13cb2063c 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o obj-$(CONFIG_IDT8T49N222A) += idt8t49n222a_serdes_clk.o obj-$(CONFIG_ZM7300) += zm7300.o obj-$(CONFIG_POWER_PFUZE100) += pfuze.o +obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze.o obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o diff --git a/board/freescale/common/pfuze.c b/board/freescale/common/pfuze.c index 69afa83562..f194d0b79d 100644 --- a/board/freescale/common/pfuze.c +++ b/board/freescale/common/pfuze.c @@ -92,4 +92,83 @@ struct pmic *pfuze_common_init(unsigned char i2cbus) return p; } +#else +int pfuze_mode_init(struct udevice *dev, u32 mode) +{ + unsigned char offset, i, switch_num; + u32 id; + int ret; + + id = pmic_reg_read(dev, PFUZE100_DEVICEID); + id = id & 0xf; + + if (id == 0) { + switch_num = 6; + offset = PFUZE100_SW1CMODE; + } else if (id == 1) { + switch_num = 4; + offset = PFUZE100_SW2MODE; + } else { + printf("Not supported, id=%d\n", id); + return -EINVAL; + } + + ret = pmic_reg_write(dev, PFUZE100_SW1ABMODE, mode); + if (ret < 0) { + printf("Set SW1AB mode error!\n"); + return ret; + } + + for (i = 0; i < switch_num - 1; i++) { + ret = pmic_reg_write(dev, offset + i * SWITCH_SIZE, mode); + if (ret < 0) { + printf("Set switch 0x%x mode error!\n", + offset + i * SWITCH_SIZE); + return ret; + } + } + + return ret; +} + +struct udevice *pfuze_common_init(void) +{ + struct udevice *dev; + int ret; + unsigned int reg, dev_id, rev_id; + + ret = pmic_get("pfuze100", &dev); + if (ret == -ENODEV) + return NULL; + + dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID); + rev_id = pmic_reg_read(dev, PFUZE100_REVID); + printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id); + + /* Set SW1AB stanby volage to 0.975V */ + reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg); + + /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ + reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg); + + /* Set SW1C standby voltage to 0.975V */ + reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY); + reg &= ~SW1x_STBY_MASK; + reg |= SW1x_0_975V; + pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg); + + /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */ + reg = pmic_reg_read(dev, PFUZE100_SW1CCONF); + reg &= ~SW1xCONF_DVSSPEED_MASK; + reg |= SW1xCONF_DVSSPEED_4US; + pmic_reg_write(dev, PFUZE100_SW1CCONF, reg); + + return dev; +} #endif diff --git a/board/freescale/common/pfuze.h b/board/freescale/common/pfuze.h index 53cfc99225..3f8c107f6b 100644 --- a/board/freescale/common/pfuze.h +++ b/board/freescale/common/pfuze.h @@ -7,7 +7,12 @@ #ifndef __PFUZE_BOARD_HELPER__ #define __PFUZE_BOARD_HELPER__ +#ifdef CONFIG_DM_PMIC_PFUZE100 +struct udevice *pfuze_common_init(void); +int pfuze_mode_init(struct udevice *dev, u32 mode); +#else struct pmic *pfuze_common_init(unsigned char i2cbus); int pfuze_mode_init(struct pmic *p, u32 mode); +#endif #endif -- cgit From 5dfc9d3766ee74f3711747a5fc9fa763ae82747c Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:08 +0800 Subject: imx: mx6sxsabresd: Enable DM driver Enable I2C/MMC/GPIO/REGUALTOR/PMIC/USB DM drivers. There are some dependency, such as when DM MMC enabled, USB compile error. Also the i.MX I2C MMC DM driver does not support legacy GPIO interface. So enable them all together. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 369 ++++++++++------------------ configs/mx6sxsabresd_defconfig | 12 + configs/mx6sxsabresd_spl_defconfig | 12 + include/configs/mx6sxsabresd.h | 7 - 4 files changed, 149 insertions(+), 251 deletions(-) diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index 3ad2140314..8940f37208 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -26,8 +26,6 @@ #include #include #include "../common/pfuze.h" -#include -#include DECLARE_GLOBAL_DATA_PTR; @@ -39,11 +37,6 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) -#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ - PAD_CTL_ODE) - #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ PAD_CTL_SPEED_HIGH | \ PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST) @@ -54,11 +47,6 @@ DECLARE_GLOBAL_DATA_PTR; #define ENET_RX_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_SPEED_HIGH | PAD_CTL_SRE_FAST) -#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ - PAD_CTL_ODE) - #define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm) @@ -74,44 +62,6 @@ static iomux_v3_cfg_t const uart1_pads[] = { MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), }; -static iomux_v3_cfg_t const usdhc2_pads[] = { - MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), -}; - -static iomux_v3_cfg_t const usdhc3_pads[] = { - MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - - /* CD pin */ - MX6_PAD_KEY_COL0__GPIO2_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL), - - /* RST_B, used for power reset cycle */ - MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -static iomux_v3_cfg_t const usdhc4_pads[] = { - MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DATA7__GPIO6_IO_21 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - static iomux_v3_cfg_t const fec1_pads[] = { MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), @@ -166,9 +116,11 @@ static int setup_fec(void) ARRAY_SIZE(phy_control_pads)); /* Enable the ENET power, active low */ + gpio_request(IMX_GPIO_NR(2, 6), "enet_rst"); gpio_direction_output(IMX_GPIO_NR(2, 6) , 0); /* Reset AR8031 PHY */ + gpio_request(IMX_GPIO_NR(2, 7), "phy_rst"); gpio_direction_output(IMX_GPIO_NR(2, 7) , 0); mdelay(10); gpio_set_value(IMX_GPIO_NR(2, 7), 1); @@ -188,86 +140,28 @@ int board_eth_init(bd_t *bis) return cpu_eth_init(bis); } -#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) -/* I2C1 for PMIC */ -static struct i2c_pads_info i2c_pad_info1 = { - .scl = { - .i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC, - .gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC, - .gp = IMX_GPIO_NR(1, 0), - }, - .sda = { - .i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC, - .gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC, - .gp = IMX_GPIO_NR(1, 1), - }, -}; - int power_init_board(void) { - struct pmic *p; + struct udevice *dev; unsigned int reg; int ret; - p = pfuze_common_init(I2C_PMIC); - if (!p) + dev = pfuze_common_init(); + if (!dev) return -ENODEV; - ret = pfuze_mode_init(p, APS_PFM); + ret = pfuze_mode_init(dev, APS_PFM); if (ret < 0) return ret; /* Enable power of VGEN5 3V3, needed for SD3 */ - pmic_reg_read(p, PFUZE100_VGEN5VOL, ®); + reg = pmic_reg_read(dev, PFUZE100_VGEN5VOL); reg &= ~LDO_VOL_MASK; reg |= (LDOB_3_30V | (1 << LDO_EN)); - pmic_reg_write(p, PFUZE100_VGEN5VOL, reg); - - return 0; -} - -#ifdef CONFIG_USB_EHCI_MX6 -#define USB_OTHERREGS_OFFSET 0x800 -#define UCTRL_PWR_POL (1 << 9) - -static iomux_v3_cfg_t const usb_otg_pads[] = { - /* OGT1 */ - MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), - MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL), - /* OTG2 */ - MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL) -}; - -static void setup_usb(void) -{ - imx_iomux_v3_setup_multiple_pads(usb_otg_pads, - ARRAY_SIZE(usb_otg_pads)); -} - -int board_usb_phy_mode(int port) -{ - if (port == 1) - return USB_INIT_HOST; - else - return usb_phy_mode(port); -} - -int board_ehci_hcd_init(int port) -{ - u32 *usbnc_usb_ctrl; - - if (port > 1) - return -EINVAL; - - usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + - port * 4); - - /* Set Power polarity */ - setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); + pmic_reg_write(dev, PFUZE100_VGEN5VOL, reg); return 0; } -#endif int board_phy_config(struct phy_device *phydev) { @@ -296,138 +190,12 @@ int board_early_init_f(void) imx_iomux_v3_setup_multiple_pads(peri_3v3_pads, ARRAY_SIZE(peri_3v3_pads)); - /* Active high for ncp692 */ - gpio_direction_output(IMX_GPIO_NR(4, 16) , 1); - -#ifdef CONFIG_USB_EHCI_MX6 - setup_usb(); -#endif - return 0; } -static struct fsl_esdhc_cfg usdhc_cfg[3] = { - {USDHC2_BASE_ADDR, 0, 4}, - {USDHC3_BASE_ADDR}, - {USDHC4_BASE_ADDR}, -}; - -#define USDHC3_CD_GPIO IMX_GPIO_NR(2, 10) -#define USDHC3_PWR_GPIO IMX_GPIO_NR(2, 11) -#define USDHC4_CD_GPIO IMX_GPIO_NR(6, 21) - int board_mmc_get_env_dev(int devno) { - return devno - 1; -} - -int board_mmc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; - int ret = 0; - - switch (cfg->esdhc_base) { - case USDHC2_BASE_ADDR: - ret = 1; /* Assume uSDHC2 is always present */ - break; - case USDHC3_BASE_ADDR: - ret = !gpio_get_value(USDHC3_CD_GPIO); - break; - case USDHC4_BASE_ADDR: - ret = !gpio_get_value(USDHC4_CD_GPIO); - break; - } - - return ret; -} - -int board_mmc_init(bd_t *bis) -{ -#ifndef CONFIG_SPL_BUILD - int i, ret; - - /* - * According to the board_mmc_init() the following map is done: - * (U-Boot device node) (Physical Port) - * mmc0 USDHC2 - * mmc1 USDHC3 - * mmc2 USDHC4 - */ - for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { - switch (i) { - case 0: - imx_iomux_v3_setup_multiple_pads( - usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); - break; - case 1: - imx_iomux_v3_setup_multiple_pads( - usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); - gpio_direction_input(USDHC3_CD_GPIO); - gpio_direction_output(USDHC3_PWR_GPIO, 1); - usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); - break; - case 2: - imx_iomux_v3_setup_multiple_pads( - usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); - gpio_direction_input(USDHC4_CD_GPIO); - usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); - break; - default: - printf("Warning: you configured more USDHC controllers" - "(%d) than supported by the board\n", i + 1); - return -EINVAL; - } - - ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); - if (ret) { - printf("Warning: failed to initialize mmc dev %d\n", i); - return ret; - } - } - - return 0; -#else - struct src *src_regs = (struct src *)SRC_BASE_ADDR; - u32 val; - u32 port; - - val = readl(&src_regs->sbmr1); - - if ((val & 0xc0) != 0x40) { - printf("Not boot from USDHC!\n"); - return -EINVAL; - } - - port = (val >> 11) & 0x3; - printf("port %d\n", port); - switch (port) { - case 1: - imx_iomux_v3_setup_multiple_pads( - usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); - usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; - break; - case 2: - imx_iomux_v3_setup_multiple_pads( - usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); - gpio_direction_input(USDHC3_CD_GPIO); - gpio_direction_output(USDHC3_PWR_GPIO, 1); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); - usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; - break; - case 3: - imx_iomux_v3_setup_multiple_pads( - usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); - gpio_direction_input(USDHC4_CD_GPIO); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); - usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; - break; - } - - gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); -#endif + return devno; } #ifdef CONFIG_FSL_QSPI @@ -509,11 +277,13 @@ static int setup_lcd(void) imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads)); /* Reset the LCD */ + gpio_request(IMX_GPIO_NR(3, 27), "lcd_rst"); gpio_direction_output(IMX_GPIO_NR(3, 27) , 0); udelay(500); gpio_direction_output(IMX_GPIO_NR(3, 27) , 1); /* Set Brightness to high */ + gpio_request(IMX_GPIO_NR(6, 4), "lcd_bright"); gpio_direction_output(IMX_GPIO_NR(6, 4) , 1); return 0; @@ -525,9 +295,9 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; -#ifdef CONFIG_SYS_I2C_MXC - setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); -#endif + /* Active high for ncp692 */ + gpio_request(IMX_GPIO_NR(4, 16), "ncp692_en"); + gpio_direction_output(IMX_GPIO_NR(4, 16), 1); #ifdef CONFIG_FSL_QSPI board_qspi_init(); @@ -566,6 +336,117 @@ int checkboard(void) #include #include +static struct fsl_esdhc_cfg usdhc_cfg[3] = { + {USDHC2_BASE_ADDR, 0, 4}, + {USDHC3_BASE_ADDR}, + {USDHC4_BASE_ADDR}, +}; + +#define USDHC3_CD_GPIO IMX_GPIO_NR(2, 10) +#define USDHC3_PWR_GPIO IMX_GPIO_NR(2, 11) +#define USDHC4_CD_GPIO IMX_GPIO_NR(6, 21) + +static iomux_v3_cfg_t const usdhc2_pads[] = { + MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc3_pads[] = { + MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + + /* CD pin */ + MX6_PAD_KEY_COL0__GPIO2_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* RST_B, used for power reset cycle */ + MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc4_pads[] = { + MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD4_DATA7__GPIO6_IO_21 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_mmc_init(bd_t *bis) +{ + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + u32 val; + u32 port; + + val = readl(&src_regs->sbmr1); + + if ((val & 0xc0) != 0x40) { + printf("Not boot from USDHC!\n"); + return -EINVAL; + } + + port = (val >> 11) & 0x3; + printf("port %d\n", port); + switch (port) { + case 1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + break; + case 2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + gpio_direction_input(USDHC3_CD_GPIO); + gpio_direction_output(USDHC3_PWR_GPIO, 1); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; + break; + case 3: + imx_iomux_v3_setup_multiple_pads( + usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); + gpio_direction_input(USDHC4_CD_GPIO); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; + break; + } + + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC2_BASE_ADDR: + ret = 1; /* Assume uSDHC2 is always present */ + break; + case USDHC3_BASE_ADDR: + ret = !gpio_get_value(USDHC3_CD_GPIO); + break; + case USDHC4_BASE_ADDR: + ret = !gpio_get_value(USDHC4_CD_GPIO); + break; + } + + return ret; +} + const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = { .dram_dqm0 = 0x00000028, .dram_dqm1 = 0x00000028, diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index 9ac5236df0..9a27710a89 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -29,11 +29,23 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_MMC=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_PHYLIB=y CONFIG_PCI=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PFUZE100=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig index 6a1423bd0c..033fc6cf58 100644 --- a/configs/mx6sxsabresd_spl_defconfig +++ b/configs/mx6sxsabresd_spl_defconfig @@ -38,10 +38,22 @@ CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_DM_MMC=y CONFIG_SPI_FLASH=y CONFIG_PHYLIB=y CONFIG_PCI=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PFUZE100=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 906e677cd1..b20e436f93 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -145,19 +145,12 @@ #define CONFIG_SYS_FSL_ESDHC_ADDR USDHC4_BASE_ADDR /* I2C Configs */ -#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MXC #define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ #define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ #define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 -/* PMIC */ -#define CONFIG_POWER -#define CONFIG_POWER_I2C -#define CONFIG_POWER_PFUZE100 -#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 - /* Network */ #define CONFIG_FEC_MXC #define CONFIG_MII -- cgit From e80f9e1a37c4136299c6ea42da7c6b2fdb1eab2d Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:09 +0800 Subject: imx: mx6sxsabresd: config wdog pinmux Because kernel set WDOG_B mux before pad with the common pinctrl framwork now and wdog reset will be triggered once set WDOG_B mux with default pad setting, we set pad setting here to workaround this. Since imx_iomux_v3_setup_pad also set mux before pad setting, we set as GPIO mux firstly here to workaround it. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- board/freescale/mx6sxsabresd/mx6sxsabresd.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c index 8940f37208..34371ad34a 100644 --- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c +++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c @@ -50,6 +50,9 @@ DECLARE_GLOBAL_DATA_PTR; #define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm) +#define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm) + int dram_init(void) { gd->ram_size = imx_ddr_size(); @@ -62,6 +65,9 @@ static iomux_v3_cfg_t const uart1_pads[] = { MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), }; +static iomux_v3_cfg_t const wdog_b_pad = { + MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; static iomux_v3_cfg_t const fec1_pads[] = { MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), @@ -295,6 +301,15 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + /* + * Because kernel set WDOG_B mux before pad with the common pinctrl + * framwork now and wdog reset will be triggered once set WDOG_B mux + * with default pad setting, we set pad setting here to workaround this. + * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set + * as GPIO mux firstly here to workaround it. + */ + imx_iomux_v3_setup_pad(wdog_b_pad); + /* Active high for ncp692 */ gpio_request(IMX_GPIO_NR(4, 16), "ncp692_en"); gpio_direction_output(IMX_GPIO_NR(4, 16), 1); -- cgit From d9523fdd11dacdf7e01216c470ef1a7a4fabf0b8 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 09:32:10 +0800 Subject: imx: mx6sxsabresd: enlarge ENV offset The u-boot-dtb.imx size is about 519KB, so 8 * 64KB conflicts with u-boot-dtb.imx. Enlarge the offset to 14 * 64KB to fix it. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam --- include/configs/mx6sxsabresd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index b20e436f93..1eaaf013f7 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -203,7 +203,7 @@ #endif #endif -#define CONFIG_ENV_OFFSET (8 * SZ_64K) +#define CONFIG_ENV_OFFSET (14 * SZ_64K) #define CONFIG_ENV_SIZE SZ_8K #define CONFIG_SYS_FSL_USDHC_NUM 3 -- cgit From 67b71df277196f1649c366e52545f5bfccf56e03 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 2 Jan 2018 18:27:29 +0800 Subject: pci: imx: request gpio before use Before use GPIO, we need to request gpio first. Free gpio after use. Signed-off-by: Peng Fan Cc: Stefano Babic Cc: Fabio Estevam Reviewed-by: Stefano Babic --- drivers/pci/pcie_imx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 2900c8d9d1..90a34063b0 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -517,10 +517,12 @@ static int imx6_pcie_init_phy(void) __weak int imx6_pcie_toggle_power(void) { #ifdef CONFIG_PCIE_IMX_POWER_GPIO + gpio_request(CONFIG_PCIE_IMX_POWER_GPIO, "pcie_power"); gpio_direction_output(CONFIG_PCIE_IMX_POWER_GPIO, 0); mdelay(20); gpio_set_value(CONFIG_PCIE_IMX_POWER_GPIO, 1); mdelay(20); + gpio_free(CONFIG_PCIE_IMX_POWER_GPIO); #endif return 0; } @@ -556,10 +558,12 @@ __weak int imx6_pcie_toggle_reset(void) * state due to being previously used in U-Boot. */ #ifdef CONFIG_PCIE_IMX_PERST_GPIO + gpio_request(CONFIG_PCIE_IMX_PERST_GPIO, "pcie_reset"); gpio_direction_output(CONFIG_PCIE_IMX_PERST_GPIO, 0); mdelay(20); gpio_set_value(CONFIG_PCIE_IMX_PERST_GPIO, 1); mdelay(20); + gpio_free(CONFIG_PCIE_IMX_PERST_GPIO); #else puts("WARNING: Make sure the PCIe #PERST line is connected!\n"); #endif -- cgit From 6a2ccd64c3adc87687fe0f232e8775274ac1ae21 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 1 Jan 2018 22:51:45 -0200 Subject: mx6: ddr: Do not access MMDC_P1_BASE_ADDR on i.MX6ULL i.MX6ULL also does not have a MMDC_P1_BASE_ADDR, so do not try to access it. Signed-off-by: Fabio Estevam Reviewed-by: Peng Fan Reviewed-by: Stefano Babic --- arch/arm/mach-imx/mx6/ddr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c index 52a9a25904..39dbd2f607 100644 --- a/arch/arm/mach-imx/mx6/ddr.c +++ b/arch/arm/mach-imx/mx6/ddr.c @@ -908,7 +908,7 @@ void mx6sdl_dram_iocfg(unsigned width, #define MR(val, ba, cmd, cs1) \ ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) #define MMDC1(entry, value) do { \ - if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl()) \ + if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl()) \ mmdc1->entry = value; \ } while (0) @@ -1215,7 +1215,7 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, u16 mem_speed = ddr3_cfg->mem_speed; mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl()) + if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl()) mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; /* Limit mem_speed for MX6D/MX6Q */ -- cgit From afe8e1b03362f169b2f905d20e2b352aca9d522e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 3 Jan 2018 08:52:02 +0800 Subject: spi: fsl_qspi: support i.MX6UL/6ULLL/7D The QSPI module on i.MX7D is modified from i.MX6SX. The module used on i.MX6UL/6ULL is reused from i.MX7D. They share same tx buffer size. The endianness is not set at qspi driver initialization. So if we don't boot from QSPI, we will get wrong endianness when accessing from AHB address directly. Add the compatible entry for 6ul/7d. Signed-off-by: Peng Fan --- drivers/spi/fsl_qspi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 0f3f7d97f0..2f5345f1cf 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -20,7 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; #define RX_BUFFER_SIZE 0x80 -#ifdef CONFIG_MX6SX +#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \ + defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D) #define TX_BUFFER_SIZE 0x200 #else #define TX_BUFFER_SIZE 0x40 @@ -268,7 +269,8 @@ static void qspi_set_lut(struct fsl_qspi_priv *priv) INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) | INSTR1(LUT_ADDR)); #endif -#ifdef CONFIG_MX6SX +#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \ + defined(CONFIG_MX6ULL) || defined(CONFIG_MX7D) /* * To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly. * So, Use IDATSZ in IPCR to determine the size and here set 0. @@ -905,6 +907,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, qspi->slave.max_write_size = TX_BUFFER_SIZE; mcr_val = qspi_read32(qspi->priv.flags, ®s->mcr); + + /* Set endianness to LE for i.mx */ + if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7)) + mcr_val = QSPI_MCR_END_CFD_LE; + qspi_write32(qspi->priv.flags, ®s->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK | (mcr_val & QSPI_MCR_END_CFD_MASK)); @@ -1023,6 +1030,11 @@ static int fsl_qspi_probe(struct udevice *bus) } mcr_val = qspi_read32(priv->flags, &priv->regs->mcr); + + /* Set endianness to LE for i.mx */ + if (IS_ENABLED(CONFIG_MX6) || IS_ENABLED(CONFIG_MX7)) + mcr_val = QSPI_MCR_END_CFD_LE; + qspi_write32(priv->flags, &priv->regs->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK | (mcr_val & QSPI_MCR_END_CFD_MASK)); @@ -1227,6 +1239,8 @@ static const struct dm_spi_ops fsl_qspi_ops = { static const struct udevice_id fsl_qspi_ids[] = { { .compatible = "fsl,vf610-qspi" }, { .compatible = "fsl,imx6sx-qspi" }, + { .compatible = "fsl,imx6ul-qspi" }, + { .compatible = "fsl,imx7d-qspi" }, { } }; -- cgit From a3cc43551f8f1cab156d02a44999c07a7261fd14 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 3 Jan 2018 08:52:03 +0800 Subject: imx: mx6ull-14x14-evk: enable DM QSPI driver To support QSPI DM driver - Add spi0 alias for qspi node. Which is used for bus number 0. - Modify the n25q256a@0 compatible property to "spi-flash". - Modify spi4 (gpio_spi) node to spi5 - Define DM SPI/QSPI related config to enable QSPI Signed-off-by: Peng Fan --- arch/arm/dts/imx6ull-14x14-evk.dts | 5 +++-- arch/arm/dts/imx6ull.dtsi | 9 +++++---- configs/mx6ull_14x14_evk_defconfig | 6 ++++++ configs/mx6ull_14x14_evk_plugin_defconfig | 6 ++++++ include/configs/mx6ullevk.h | 10 ++++++++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/imx6ull-14x14-evk.dts b/arch/arm/dts/imx6ull-14x14-evk.dts index 375bd4ea31..2a941bff1c 100644 --- a/arch/arm/dts/imx6ull-14x14-evk.dts +++ b/arch/arm/dts/imx6ull-14x14-evk.dts @@ -67,7 +67,7 @@ }; }; - spi4 { + spi5 { compatible = "spi-gpio"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi4>; @@ -455,7 +455,8 @@ flash0: n25q256a@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q256a"; + /* compatible = "micron,n25q256a"; */ + compatible = "spi-flash"; spi-max-frequency = <29000000>; spi-nor,ddr-quad-read-dummy = <6>; reg = <0>; diff --git a/arch/arm/dts/imx6ull.dtsi b/arch/arm/dts/imx6ull.dtsi index 65950e8019..ea882a7f14 100644 --- a/arch/arm/dts/imx6ull.dtsi +++ b/arch/arm/dts/imx6ull.dtsi @@ -38,10 +38,11 @@ serial5 = &uart6; serial6 = &uart7; serial7 = &uart8; - spi0 = &ecspi1; - spi1 = &ecspi2; - spi2 = &ecspi3; - spi3 = &ecspi4; + spi0 = &qspi; + spi1 = &ecspi1; + spi2 = &ecspi2; + spi3 = &ecspi3; + spi4 = &ecspi4; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig index 4960056fe4..5305c12fdb 100644 --- a/configs/mx6ull_14x14_evk_defconfig +++ b/configs/mx6ull_14x14_evk_defconfig @@ -10,6 +10,7 @@ CONFIG_CMD_MEMTEST=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_CACHE=y @@ -24,7 +25,12 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_STMICRO=y CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y CONFIG_DM_SPI=y +CONFIG_FSL_QSPI=y diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig index d07be226f5..f1023b2aae 100644 --- a/configs/mx6ull_14x14_evk_plugin_defconfig +++ b/configs/mx6ull_14x14_evk_plugin_defconfig @@ -11,6 +11,7 @@ CONFIG_CMD_MEMTEST=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_CACHE=y @@ -25,7 +26,12 @@ CONFIG_DM_GPIO=y CONFIG_DM_74X164=y CONFIG_DM_I2C=y CONFIG_DM_MMC=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_STMICRO=y CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR=y CONFIG_DM_SPI=y +CONFIG_FSL_QSPI=y diff --git a/include/configs/mx6ullevk.h b/include/configs/mx6ullevk.h index 8787df4907..6a48742fd0 100644 --- a/include/configs/mx6ullevk.h +++ b/include/configs/mx6ullevk.h @@ -164,4 +164,14 @@ #define CONFIG_SOFT_SPI +#ifdef CONFIG_FSL_QSPI +#define CONFIG_SYS_FSL_QSPI_AHB +#define CONFIG_SF_DEFAULT_BUS 0 +#define CONFIG_SF_DEFAULT_CS 0 +#define CONFIG_SF_DEFAULT_SPEED 40000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0 +#define FSL_QSPI_FLASH_NUM 1 +#define FSL_QSPI_FLASH_SIZE SZ_32M +#endif + #endif -- cgit From cd9f3ff651cdbe397c4a3da978322e942bdf5298 Mon Sep 17 00:00:00 2001 From: Eran Matityahu Date: Wed, 3 Jan 2018 12:53:08 +0200 Subject: imx7: spl: Use SPL boot device MMC1 for all of the SOCs MMC/SD boot devices Use only one SPL MMC device, similarly to the iMX6 code Signed-off-by: Eran Matityahu --- arch/arm/mach-imx/spl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 723f51fad3..5e0338fc4c 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -106,10 +106,9 @@ u32 spl_boot_device(void) switch (boot_device_spl) { case SD1_BOOT: case MMC1_BOOT: - return BOOT_DEVICE_MMC1; case SD2_BOOT: case MMC2_BOOT: - return BOOT_DEVICE_MMC2; + return BOOT_DEVICE_MMC1; case SPI_NOR_BOOT: return BOOT_DEVICE_SPI; default: -- cgit From e7528a3d7436fd0d073ecdd8527f9a0dc535e172 Mon Sep 17 00:00:00 2001 From: Eran Matityahu Date: Wed, 3 Jan 2018 12:56:24 +0200 Subject: imx7: spl: Add support for MMC3, SD3 and NAND boot devices Signed-off-by: Eran Matityahu --- arch/arm/mach-imx/spl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 5e0338fc4c..346fc0bee9 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -108,7 +108,11 @@ u32 spl_boot_device(void) case MMC1_BOOT: case SD2_BOOT: case MMC2_BOOT: + case SD3_BOOT: + case MMC3_BOOT: return BOOT_DEVICE_MMC1; + case NAND_BOOT: + return BOOT_DEVICE_NAND; case SPI_NOR_BOOT: return BOOT_DEVICE_SPI; default: -- cgit From 20b9f2eaf5fbb1e7befbdc4f7863fd69c942d744 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 3 Jan 2018 08:52:39 -0500 Subject: arm: imx: Rework i.MX specific commands to be excluded from SPL The "clocks" and "bootaux" commands are only usable in full U-Boot, not SPL, so do not link them inside of SPL. Rework a little of the bootaux related code to make use of __weak and declare parts of it static as it's local to the file. Cc: Stefano Babic Cc: Fabio Estevam Signed-off-by: Tom Rini Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/Makefile | 2 ++ arch/arm/mach-imx/imx_bootaux.c | 13 ++++--------- arch/arm/mach-imx/mx5/clock.c | 4 +++- arch/arm/mach-imx/mx7/clock.c | 2 ++ arch/arm/mach-imx/mx7ulp/clock.c | 2 ++ 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index d7966cfd4a..cf39d08bdd 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -28,7 +28,9 @@ obj-y += cache.o init.o obj-$(CONFIG_SATA) += sata.o obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o obj-$(CONFIG_IMX_RDC) += rdc-sema.o +ifneq ($(CONFIG_SPL_BUILD),y) obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o +endif obj-$(CONFIG_SECURE_BOOT) += hab.o obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o endif diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index 69026df763..b62dfbf6bf 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -6,27 +6,22 @@ #include #include +#include /* Allow for arch specific config before we boot */ -static int __arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) +int __weak arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) { /* please define platform specific arch_auxiliary_core_up() */ return CMD_RET_FAILURE; } -int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) - __attribute__((weak, alias("__arch_auxiliary_core_up"))); - /* Allow for arch specific config before we boot */ -static int __arch_auxiliary_core_check_up(u32 core_id) +int __weak arch_auxiliary_core_check_up(u32 core_id) { /* please define platform specific arch_auxiliary_core_check_up() */ return 0; } -int arch_auxiliary_core_check_up(u32 core_id) - __attribute__((weak, alias("__arch_auxiliary_core_check_up"))); - /* * To i.MX6SX and i.MX7D, the image supported by bootaux needs * the reset vector at the head for the image, with SP and PC @@ -40,7 +35,7 @@ int arch_auxiliary_core_check_up(u32 core_id) * The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for * accessing the M4 TCMUL. */ -int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr; int ret, up; diff --git a/arch/arm/mach-imx/mx5/clock.c b/arch/arm/mach-imx/mx5/clock.c index 610098c175..284f6d4cde 100644 --- a/arch/arm/mach-imx/mx5/clock.c +++ b/arch/arm/mach-imx/mx5/clock.c @@ -911,10 +911,11 @@ void mxc_set_sata_internal_clock(void) } #endif +#ifndef CONFIG_SPL_BUILD /* * Dump some core clockes. */ -int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u32 freq; @@ -947,3 +948,4 @@ U_BOOT_CMD( "display clocks", "" ); +#endif diff --git a/arch/arm/mach-imx/mx7/clock.c b/arch/arm/mach-imx/mx7/clock.c index 8150faa1a3..c11042d6f5 100644 --- a/arch/arm/mach-imx/mx7/clock.c +++ b/arch/arm/mach-imx/mx7/clock.c @@ -1096,6 +1096,7 @@ void epdc_clock_disable(void) } #endif +#ifndef CONFIG_SPL_BUILD /* * Dump some core clockes. */ @@ -1131,3 +1132,4 @@ U_BOOT_CMD( "display clocks", "" ); +#endif diff --git a/arch/arm/mach-imx/mx7ulp/clock.c b/arch/arm/mach-imx/mx7ulp/clock.c index 77b282addd..553d62149d 100644 --- a/arch/arm/mach-imx/mx7ulp/clock.c +++ b/arch/arm/mach-imx/mx7ulp/clock.c @@ -323,6 +323,7 @@ void hab_caam_clock_enable(unsigned char enable) } #endif +#ifndef CONFIG_SPL_BUILD /* * Dump some core clockes. */ @@ -363,3 +364,4 @@ U_BOOT_CMD( "display clocks", "" ); +#endif -- cgit From c10b1c43fdd80fe01ad527e6d024bfaa19eb361a Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 3 Jan 2018 09:15:22 -0500 Subject: imx: ventana: Rework CONFIG_CMD_EECONFIG code to not be included in SPL The command can only be used from full U-Boot, so do not build it into SPL. Cc: Stefano Babic Cc: Fabio Estevam Cc: Tim Harvey Signed-off-by: Tom Rini Acked-by: Tim Harvey Reviewed-by: Fabio Estevam --- board/gateworks/gw_ventana/eeprom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c index 2c07a84fff..a435dd9fb7 100644 --- a/board/gateworks/gw_ventana/eeprom.c +++ b/board/gateworks/gw_ventana/eeprom.c @@ -119,7 +119,7 @@ struct ventana_eeprom_config econfig[] = { { /* Sentinel */ } }; -#ifdef CONFIG_CMD_EECONFIG +#if defined(CONFIG_CMD_EECONFIG) && !defined(CONFIG_SPL_BUILD) static struct ventana_eeprom_config *get_config(const char *name) { struct ventana_eeprom_config *cfg = econfig; @@ -135,7 +135,7 @@ static struct ventana_eeprom_config *get_config(const char *name) static u8 econfig_bytes[sizeof(ventana_info.config)]; static int econfig_init = -1; -int do_econfig(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_econfig(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct ventana_eeprom_config *cfg; struct ventana_board_info *info = &ventana_info; -- cgit From bf52330a507901af2a5581bec99c6da01388a335 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 3 Jan 2018 09:16:29 -0500 Subject: imx: ventana: Rework CONFIG_CMD_GSC code to not be included in SPL The command can only be used from full U-Boot, so do not build it into SPL. Cc: Stefano Babic Cc: Fabio Estevam Cc: Tim Harvey Signed-off-by: Tom Rini Acked-by: Tim Harvey Reviewed-by: Fabio Estevam --- board/gateworks/gw_ventana/gsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c index 68b1ddb532..f2a01b84de 100644 --- a/board/gateworks/gw_ventana/gsc.c +++ b/board/gateworks/gw_ventana/gsc.c @@ -172,7 +172,7 @@ int gsc_boot_wd_disable(void) return 1; } -#ifdef CONFIG_CMD_GSC +#if defined(CONFIG_CMD_GSC) && !defined(CONFIG_SPL_BUILD) static int do_gsc_sleep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { -- cgit From 64c7abf0235a3cb5efc32b6c926b6ff8cc0d1d9b Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 3 Jan 2018 09:19:17 -0500 Subject: toradex: imx6: Rework PF0100 fuse programming commands to not be in SPL The code for programming the OTP fuses on the PMIC PF0100 can only be used in full U-Boot, so do not build / link it into SPL. Cc: Max Krummenacher Cc: Stefano Babic Cc: Fabio Estevam Signed-off-by: Tom Rini Reviewed-by: Fabio Estevam Tested-by: Max Krummenacher --- board/toradex/apalis_imx6/pf0100.c | 9 ++++++--- board/toradex/apalis_imx6/pf0100.h | 3 --- board/toradex/colibri_imx6/pf0100.c | 8 +++++--- board/toradex/colibri_imx6/pf0100.h | 3 --- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/board/toradex/apalis_imx6/pf0100.c b/board/toradex/apalis_imx6/pf0100.c index 5eaf9c0b17..013801e62b 100644 --- a/board/toradex/apalis_imx6/pf0100.c +++ b/board/toradex/apalis_imx6/pf0100.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -23,7 +24,7 @@ /*#define DEBUG */ /* use Apalis GPIO1 to switch on VPGM, ON: 1 */ -static iomux_v3_cfg_t const pmic_prog_pads[] = { +static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = { MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), # define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 4) }; @@ -161,7 +162,8 @@ unsigned pmic_init(void) return programmed; } -int pf0100_prog(void) +#ifndef CONFIG_SPL_BUILD +static int pf0100_prog(void) { unsigned char bus = 1; unsigned char val; @@ -208,7 +210,7 @@ int pf0100_prog(void) return CMD_RET_SUCCESS; } -int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc, +static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret; @@ -226,3 +228,4 @@ U_BOOT_CMD( "Program the OTP fuses on the PMIC PF0100", "" ); +#endif diff --git a/board/toradex/apalis_imx6/pf0100.h b/board/toradex/apalis_imx6/pf0100.h index c84cab8b15..af1e88fbc9 100644 --- a/board/toradex/apalis_imx6/pf0100.h +++ b/board/toradex/apalis_imx6/pf0100.h @@ -50,7 +50,4 @@ /* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */ unsigned pmic_init(void); -/* programmes OTP fuses to values required on a Toradex Apalis iMX6 */ -int pf0100_prog(void); - #endif /* PF0100_H_ */ diff --git a/board/toradex/colibri_imx6/pf0100.c b/board/toradex/colibri_imx6/pf0100.c index 6889287760..62e64ab1d7 100644 --- a/board/toradex/colibri_imx6/pf0100.c +++ b/board/toradex/colibri_imx6/pf0100.c @@ -23,7 +23,7 @@ /*#define DEBUG */ /* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */ -static iomux_v3_cfg_t const pmic_prog_pads[] = { +static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = { MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(NO_PAD_CTRL), # define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3) }; @@ -144,7 +144,8 @@ unsigned pmic_init(void) return programmed; } -int pf0100_prog(void) +#ifndef CONFIG_SPL_BUILD +static int pf0100_prog(void) { unsigned char bus = 1; unsigned char val; @@ -191,7 +192,7 @@ int pf0100_prog(void) return CMD_RET_SUCCESS; } -int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc, +static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret; @@ -209,3 +210,4 @@ U_BOOT_CMD( "Program the OTP fuses on the PMIC PF0100", "" ); +#endif diff --git a/board/toradex/colibri_imx6/pf0100.h b/board/toradex/colibri_imx6/pf0100.h index c84cab8b15..af1e88fbc9 100644 --- a/board/toradex/colibri_imx6/pf0100.h +++ b/board/toradex/colibri_imx6/pf0100.h @@ -50,7 +50,4 @@ /* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */ unsigned pmic_init(void); -/* programmes OTP fuses to values required on a Toradex Apalis iMX6 */ -int pf0100_prog(void); - #endif /* PF0100_H_ */ -- cgit From db00e921fdc6af54492606dd0ebd1f0ab53c7a90 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 3 Jan 2018 12:55:34 -0200 Subject: mx6memcal: Fix the UART ports for mx6sabresd/auto boards mx6sabresd board uses the following pins for console: PAD_CSI0_DAT10__UART1_TX_DATA PAD_CSI0_DAT11__UART1_RX_DATA ,so put it in the same config option as wandboard. mx6sabreauto board uses the following pins for console: PAD_KEY_COL0__UART4_TX_DATA PAD_KEY_ROW0__UART4_RX_DATA So do not mention sabreauto board as part of the UART1_SD3_DAT6_7 option. The config option for sabreauto can be added later when needed. Signed-off-by: Fabio Estevam --- board/freescale/mx6memcal/Kconfig | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/board/freescale/mx6memcal/Kconfig b/board/freescale/mx6memcal/Kconfig index 443804dc11..9987cba5dc 100644 --- a/board/freescale/mx6memcal/Kconfig +++ b/board/freescale/mx6memcal/Kconfig @@ -45,20 +45,12 @@ choice NXP SABRELite. config UART1_CSI0_DAT10_11 - bool "UART1 on CSI0_DAT10/11 (Wand)" + bool "UART1 on CSI0_DAT10/11 (Wand, SabreSD)" depends on SERIAL_CONSOLE_UART1 help Choose this configuration if you're using pads CSI0_DAT10 and DAT11 for a console on UART1 as - is done on the i.MX6 Wand board. - - config UART1_SD3_DAT6_7 - bool "UART1 on SD3_DAT6/7 (SabreSD, SabreAuto)" - depends on SERIAL_CONSOLE_UART1 - help - Choose this configuration if you're using pads - SD3_DAT6 and DAT7 for a console on UART1 as is - done on the NXP SABRESD or SABREAUTO designs. + is done on the i.MX6 Wand board and i.MX6 SabreSD. config UART1_UART1 bool "UART1 on UART1 (i.MX6SL EVK, WaRP)" -- cgit From 941fcabfa762c2a8b26238ec5cce520253d7388b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 3 Jan 2018 12:55:35 -0200 Subject: mx6memcal: spl: Also take i.MX6ULL into account i.MX6ULL also does not support 64-bit DDR bus, so add it to the check logic. Signed-off-by: Fabio Estevam --- board/freescale/mx6memcal/spl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c index 8ee89ff116..e8b992c2b6 100644 --- a/board/freescale/mx6memcal/spl.c +++ b/board/freescale/mx6memcal/spl.c @@ -419,6 +419,7 @@ void board_init_f(ulong dummy) if (sysinfo.dsize != 1) { if (is_cpu_type(MXC_CPU_MX6SX) || is_cpu_type(MXC_CPU_MX6UL) || + is_cpu_type(MXC_CPU_MX6ULL) || is_cpu_type(MXC_CPU_MX6SL)) { printf("cpu type 0x%x doesn't support 64-bit bus\n", get_cpu_type()); -- cgit From 0f194018f2b431ce81606c2b6be7c8992d09c749 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 3 Jan 2018 12:55:36 -0200 Subject: mx6memcal: spl: Disambiguate the error message Currently mmdc_do_dqs_calibration() and mmdc_do_write_level_calibration() show the same error message, which is confusing for debugging. Disambiguate the mmdc_do_dqs_calibration() error message. Signed-off-by: Fabio Estevam --- board/freescale/mx6memcal/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/mx6memcal/spl.c b/board/freescale/mx6memcal/spl.c index e8b992c2b6..027da4fbbc 100644 --- a/board/freescale/mx6memcal/spl.c +++ b/board/freescale/mx6memcal/spl.c @@ -446,7 +446,7 @@ void board_init_f(ulong dummy) } else { errs = mmdc_do_dqs_calibration(&sysinfo); if (errs) { - printf("error %d from write level calibration\n", errs); + printf("error %d from dqs calibration\n", errs); } else { printf("completed successfully\n"); mmdc_read_calibration(&sysinfo, &calibration); -- cgit From f57263ee9bb8b5d9f39b48d09d21114c9dbb6a02 Mon Sep 17 00:00:00 2001 From: Koen Vandeputte Date: Thu, 4 Jan 2018 14:54:34 +0100 Subject: drivers: pci: imx: fix enumeration logic error By default, the subordinate is set equally to the secondary bus (1) when the RC boots, and does not alter afterwards. This means that theoretically, the highest bus reachable downstream is bus 1. Force the PCIe RC subordinate to 0xff, otherwise no downstream devices will be detected behind bus 1 if the booting OS does not allow enumerating a higher busnr than the subordinate value of the primary bus. Signed-off-by: Koen Vandeputte --- drivers/pci/pcie_imx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c index 90a34063b0..ef66a1d3f4 100644 --- a/drivers/pci/pcie_imx.c +++ b/drivers/pci/pcie_imx.c @@ -615,6 +615,17 @@ static int imx_pcie_link_up(void) imx_pcie_regions_setup(); + /* + * By default, the subordinate is set equally to the secondary + * bus (0x01) when the RC boots. + * This means that theoretically, only bus 1 is reachable from the RC. + * Force the PCIe RC subordinate to 0xff, otherwise no downstream + * devices will be detected if the enumeration is applied strictly. + */ + tmp = readl(MX6_DBI_ADDR + 0x18); + tmp |= (0xff << 16); + writel(tmp, MX6_DBI_ADDR + 0x18); + /* * FIXME: Force the PCIe RC to Gen1 operation * The RC must be forced into Gen1 mode before bringing the link -- cgit From dbeaa1d1317bf6494adb43417d2407672fc94ba6 Mon Sep 17 00:00:00 2001 From: Christopher Spinrath Date: Tue, 9 Jan 2018 22:01:35 +0100 Subject: ARM: imx: cm_fx6: export board and soc info to env Like many other i.MX6 based boards, there are multiple variants of the cm-fx6 module featuring different SoC variants. Furthermore, the module can be paired with multiple baseboards. At the same time modern distribution like Fedora require U-Boot to select a proper devicetree which depends on the SoC variant and the baseboard. Thus, export the SoC variant and the actual board to the environment following the conventions of other i.MX6 devices (e.g. the NXP boards) such that the environment can select a devicetree file to load. For now, we only know for sure that the cm-fx6 module and the SB-fx6m baseboard amount to a Utilite Computer variant (depending on the SoC). Further combinations may be added in the future; e.g. CompuLab's evaluation board once someone can verify the identification string stored in its eeprom. Signed-off-by: Christopher Spinrath Reviewed-by: Stefano Babic --- arch/arm/mach-imx/mx6/Kconfig | 1 + board/compulab/cm_fx6/cm_fx6.c | 21 +++++++++++++++++++++ include/configs/cm_fx6.h | 1 + 3 files changed, 23 insertions(+) diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index c11c02c87b..2f3e52d624 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -130,6 +130,7 @@ config TARGET_CM_FX6 bool "CM-FX6" select SUPPORT_SPL select MX6QDL + select BOARD_LATE_INIT select DM select DM_SERIAL select DM_GPIO diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c index 620c3f2d0d..673de03071 100644 --- a/board/compulab/cm_fx6/cm_fx6.c +++ b/board/compulab/cm_fx6/cm_fx6.c @@ -621,6 +621,27 @@ int board_init(void) return 0; } +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + char baseboard_name[16]; + int err; + + if (is_mx6dq()) + env_set("board_rev", "MX6Q"); + else if (is_mx6dl()) + env_set("board_rev", "MX6DL"); + + err = cl_eeprom_get_product_name((uchar *)baseboard_name, 0); + if (err) + return 0; + + if (!strncmp("SB-FX6m", baseboard_name, 7)) + env_set("board_name", "Utilite"); +#endif + return 0; +} + int checkboard(void) { puts("Board: CM-FX6\n"); diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index ec3e6e6ca5..cb71ea8811 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -67,6 +67,7 @@ #define CONFIG_ENV_OFFSET (768 * 1024) #ifndef CONFIG_SPL_BUILD +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG #define CONFIG_EXTRA_ENV_SETTINGS \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ -- cgit From edc57f1df8973e296e213819568ac116def0066a Mon Sep 17 00:00:00 2001 From: Christopher Spinrath Date: Tue, 9 Jan 2018 22:01:36 +0100 Subject: ARM: imx: cm_fx6: env: try to determine dtb to use Some distributions like Fedora expect U-Boot to select a proper devicetree. Since there are several variants of the cm-fx6 module featuring different SoC variants and the module can be paired with several baseboards, it is not viable to hardcode a filename. Instead, follow the lead of other i.MX6 based devices and try to determine the devicetree to use with the help of the board name and the SoC variant exported by the board code, before calling the distro bootcommand. For now, only for the Utilite Pro a proper devicetree filename is known but further variants of the Utilite Computer or other devices based on the cm-fx6 module may be added in the future. Signed-off-by: Christopher Spinrath --- configs/cm_fx6_defconfig | 2 +- include/configs/cm_fx6.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig index 33e610ccb4..6b1c0a823c 100644 --- a/configs/cm_fx6_defconfig +++ b/configs/cm_fx6_defconfig @@ -16,7 +16,7 @@ CONFIG_DISTRO_DEFAULTS=y CONFIG_OF_BOARD_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" CONFIG_BOOTDELAY=3 -CONFIG_BOOTCOMMAND="run distro_bootcmd; run legacy_bootcmd" +CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd; run legacy_bootcmd" CONFIG_SPL=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x80 CONFIG_SPL_I2C_SUPPORT=y diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h index cb71ea8811..da870b9baa 100644 --- a/include/configs/cm_fx6.h +++ b/include/configs/cm_fx6.h @@ -76,6 +76,7 @@ "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ "pxefile_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \ "scriptaddr=" __stringify(CONFIG_LOADADDR) "\0" \ + "fdtfile=undefined\0" \ "stdin=serial,usbkbd\0" \ "stdout=serial,vga\0" \ "stderr=serial,vga\0" \ @@ -153,6 +154,11 @@ "fi;" \ "run setupnandboot;" \ "run nandboot;\0" \ + "findfdt="\ + "if test $board_name = Utilite && test $board_rev = MX6Q ; then " \ + "setenv fdtfile imx6q-utilite-pro.dtb; fi; " \ + "if test $fdtfile = undefined; then " \ + "echo WARNING: Could not determine dtb to use; fi; \0" \ BOOTENV #define CONFIG_PREBOOT "usb start;sf probe" -- cgit From adbb051f0897f5b41e9514ca4f974738396be6d6 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:39:55 +0000 Subject: arm: imx: hab: Make authenticate_image return int Both usages of authenticate_image treat the result code as a simple binary. The command line usage of authenticate_image directly returns the result code of authenticate_image as a success/failure code. Right now when calling hab_auth_img and test the result code in a shell a passing hab_auth_img will appear to the shell as a fail. The first step in fixing this behaviour is to fix-up the result code return by authenticate_image() itself, subsequent patches fix the interpretation of authenticate_image so that zero will return CMD_RET_SUCCESS and non-zero will return CMD_RET_FAILURE. The first step is fixing the return type in authenticate_image() so do that now. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 2 +- arch/arm/mach-imx/hab.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index e0ff459d53..1b7a5e4440 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -145,6 +145,6 @@ typedef void hapi_clock_init_t(void); /* ----------- end of HAB API updates ------------*/ -uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size); +int authenticate_image(uint32_t ddr_start, uint32_t image_size); #endif diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 02c7ae4e72..09892a6840 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -410,7 +410,7 @@ static bool is_hab_enabled(void) return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT; } -uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) +int authenticate_image(uint32_t ddr_start, uint32_t image_size) { uint32_t load_addr = 0; size_t bytes; -- cgit From 9535b3975f6731736ebe0e6b9461502784d5e4d0 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:39:56 +0000 Subject: arm: imx: hab: Fix authenticate_image result code authenticate_image returns 1 for success and 0 for failure. That result code is mapped directly to the result code for the command line function hab_auth_img - which means when hab_auth_img succeeds it is returning CMD_RET_FAILURE (1) instead of CMD_RET_SUCCESS (0). This patch fixes this behaviour by making authenticate_image() return 0 for success and 1 for failure. Both users of authenticate_image() as a result have some minimal churn. The upshot is once done when hab_auth_img is called from the command line we set $? in the standard way for scripting functions to act on. Fixes: 36c1ca4d46ef ("imx: Support i.MX6 High Assurance Boot authentication") Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 9 ++++++--- arch/arm/mach-imx/spl.c | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 09892a6840..9fe6d43203 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -373,7 +373,10 @@ static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, ivt_offset = simple_strtoul(argv[2], NULL, 16); rcode = authenticate_image(addr, ivt_offset); - + if (rcode == 0) + rcode = CMD_RET_SUCCESS; + else + rcode = CMD_RET_FAILURE; return rcode; } @@ -415,7 +418,7 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) uint32_t load_addr = 0; size_t bytes; ptrdiff_t ivt_offset = 0; - int result = 0; + int result = 1; ulong start; hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; hab_rvt_entry_t *hab_rvt_entry; @@ -510,7 +513,7 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) } if ((!is_hab_enabled()) || (load_addr != 0)) - result = 1; + result = 0; return result; } diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 346fc0bee9..31b4b0fcfc 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -166,8 +166,8 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) /* HAB looks for the CSF at the end of the authenticated data therefore, * we need to subtract the size of the CSF from the actual filesize */ - if (authenticate_image(spl_image->load_addr, - spl_image->size - CONFIG_CSF_SIZE)) { + if (!authenticate_image(spl_image->load_addr, + spl_image->size - CONFIG_CSF_SIZE)) { image_entry(); } else { puts("spl: ERROR: image authentication unsuccessful\n"); -- cgit From d2c61800fc1ece786799262c71d4789b0fa56279 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:39:57 +0000 Subject: arm: imx: hab: Optimise flow of authenticate_image on is_enabled fail There is no need to call is_enabled() twice in authenticate_image - it does nothing but add an additional layer of indentation. We can check for is_enabled() at the start of the function and return the result code directly. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 138 ++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 9fe6d43203..6f86c02efb 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -428,91 +428,91 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) hab_rvt_entry = hab_rvt_entry_p; hab_rvt_exit = hab_rvt_exit_p; - if (is_hab_enabled()) { - printf("\nAuthenticate image from DDR location 0x%x...\n", - ddr_start); + if (!is_hab_enabled()) { + puts("hab fuse not enabled\n"); + return result; + } - hab_caam_clock_enable(1); + printf("\nAuthenticate image from DDR location 0x%x...\n", + ddr_start); - if (hab_rvt_entry() == HAB_SUCCESS) { - /* If not already aligned, Align to ALIGN_SIZE */ - ivt_offset = (image_size + ALIGN_SIZE - 1) & - ~(ALIGN_SIZE - 1); + hab_caam_clock_enable(1); - start = ddr_start; - bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; + if (hab_rvt_entry() == HAB_SUCCESS) { + /* If not already aligned, Align to ALIGN_SIZE */ + ivt_offset = (image_size + ALIGN_SIZE - 1) & + ~(ALIGN_SIZE - 1); + + start = ddr_start; + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; #ifdef DEBUG - printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", - ivt_offset, ddr_start + ivt_offset); - puts("Dumping IVT\n"); - print_buffer(ddr_start + ivt_offset, - (void *)(ddr_start + ivt_offset), - 4, 0x8, 0); - - puts("Dumping CSF Header\n"); - print_buffer(ddr_start + ivt_offset+IVT_SIZE, - (void *)(ddr_start + ivt_offset+IVT_SIZE), - 4, 0x10, 0); + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", + ivt_offset, ddr_start + ivt_offset); + puts("Dumping IVT\n"); + print_buffer(ddr_start + ivt_offset, + (void *)(ddr_start + ivt_offset), + 4, 0x8, 0); + + puts("Dumping CSF Header\n"); + print_buffer(ddr_start + ivt_offset + IVT_SIZE, + (void *)(ddr_start + ivt_offset + IVT_SIZE), + 4, 0x10, 0); #if !defined(CONFIG_SPL_BUILD) - get_hab_status(); + get_hab_status(); #endif - puts("\nCalling authenticate_image in ROM\n"); - printf("\tivt_offset = 0x%x\n", ivt_offset); - printf("\tstart = 0x%08lx\n", start); - printf("\tbytes = 0x%x\n", bytes); + puts("\nCalling authenticate_image in ROM\n"); + printf("\tivt_offset = 0x%x\n", ivt_offset); + printf("\tstart = 0x%08lx\n", start); + printf("\tbytes = 0x%x\n", bytes); #endif - /* - * If the MMU is enabled, we have to notify the ROM - * code, or it won't flush the caches when needed. - * This is done, by setting the "pu_irom_mmu_enabled" - * word to 1. You can find its address by looking in - * the ROM map. This is critical for - * authenticate_image(). If MMU is enabled, without - * setting this bit, authentication will fail and may - * crash. - */ - /* Check MMU enabled */ - if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) { - if (is_mx6dq()) { - /* - * This won't work on Rev 1.0.0 of - * i.MX6Q/D, since their ROM doesn't - * do cache flushes. don't think any - * exist, so we ignore them. - */ - if (!is_mx6dqp()) - writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); - } else if (is_mx6sdl()) { - writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); - } else if (is_mx6sl()) { - writel(1, MX6SL_PU_IROM_MMU_EN_VAR); - } + /* + * If the MMU is enabled, we have to notify the ROM + * code, or it won't flush the caches when needed. + * This is done, by setting the "pu_irom_mmu_enabled" + * word to 1. You can find its address by looking in + * the ROM map. This is critical for + * authenticate_image(). If MMU is enabled, without + * setting this bit, authentication will fail and may + * crash. + */ + /* Check MMU enabled */ + if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) { + if (is_mx6dq()) { + /* + * This won't work on Rev 1.0.0 of + * i.MX6Q/D, since their ROM doesn't + * do cache flushes. don't think any + * exist, so we ignore them. + */ + if (!is_mx6dqp()) + writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); + } else if (is_mx6sdl()) { + writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); + } else if (is_mx6sl()) { + writel(1, MX6SL_PU_IROM_MMU_EN_VAR); } + } - load_addr = (uint32_t)hab_rvt_authenticate_image( - HAB_CID_UBOOT, - ivt_offset, (void **)&start, - (size_t *)&bytes, NULL); - if (hab_rvt_exit() != HAB_SUCCESS) { - puts("hab exit function fail\n"); - load_addr = 0; - } - } else { - puts("hab entry function fail\n"); + load_addr = (uint32_t)hab_rvt_authenticate_image( + HAB_CID_UBOOT, + ivt_offset, (void **)&start, + (size_t *)&bytes, NULL); + if (hab_rvt_exit() != HAB_SUCCESS) { + puts("hab exit function fail\n"); + load_addr = 0; } + } else { + puts("hab entry function fail\n"); + } - hab_caam_clock_enable(0); + hab_caam_clock_enable(0); #if !defined(CONFIG_SPL_BUILD) - get_hab_status(); + get_hab_status(); #endif - } else { - puts("hab fuse not enabled\n"); - } - - if ((!is_hab_enabled()) || (load_addr != 0)) + if (load_addr != 0) result = 0; return result; -- cgit From 53c8a510e72a87aa1d6eda48c5462b01a215e518 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:39:58 +0000 Subject: arm: imx: hab: Optimise flow of authenticate_image on hab_entry fail The current code disjoins an entire block of code on hab_entry pass/fail resulting in a large chunk of authenticate_image being offset to the right. Fix this by checking hab_entry() pass/failure and exiting the function directly if in an error state. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 118 ++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 6f86c02efb..f878b7bf9d 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -438,75 +438,77 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) hab_caam_clock_enable(1); - if (hab_rvt_entry() == HAB_SUCCESS) { - /* If not already aligned, Align to ALIGN_SIZE */ - ivt_offset = (image_size + ALIGN_SIZE - 1) & - ~(ALIGN_SIZE - 1); + if (hab_rvt_entry() != HAB_SUCCESS) { + puts("hab entry function fail\n"); + goto hab_caam_clock_disable; + } - start = ddr_start; - bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; + /* If not already aligned, Align to ALIGN_SIZE */ + ivt_offset = (image_size + ALIGN_SIZE - 1) & + ~(ALIGN_SIZE - 1); + + start = ddr_start; + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; #ifdef DEBUG - printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", - ivt_offset, ddr_start + ivt_offset); - puts("Dumping IVT\n"); - print_buffer(ddr_start + ivt_offset, - (void *)(ddr_start + ivt_offset), - 4, 0x8, 0); - - puts("Dumping CSF Header\n"); - print_buffer(ddr_start + ivt_offset + IVT_SIZE, - (void *)(ddr_start + ivt_offset + IVT_SIZE), - 4, 0x10, 0); + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", + ivt_offset, ddr_start + ivt_offset); + puts("Dumping IVT\n"); + print_buffer(ddr_start + ivt_offset, + (void *)(ddr_start + ivt_offset), + 4, 0x8, 0); + + puts("Dumping CSF Header\n"); + print_buffer(ddr_start + ivt_offset + IVT_SIZE, + (void *)(ddr_start + ivt_offset + IVT_SIZE), + 4, 0x10, 0); #if !defined(CONFIG_SPL_BUILD) - get_hab_status(); + get_hab_status(); #endif - puts("\nCalling authenticate_image in ROM\n"); - printf("\tivt_offset = 0x%x\n", ivt_offset); - printf("\tstart = 0x%08lx\n", start); - printf("\tbytes = 0x%x\n", bytes); + puts("\nCalling authenticate_image in ROM\n"); + printf("\tivt_offset = 0x%x\n", ivt_offset); + printf("\tstart = 0x%08lx\n", start); + printf("\tbytes = 0x%x\n", bytes); #endif - /* - * If the MMU is enabled, we have to notify the ROM - * code, or it won't flush the caches when needed. - * This is done, by setting the "pu_irom_mmu_enabled" - * word to 1. You can find its address by looking in - * the ROM map. This is critical for - * authenticate_image(). If MMU is enabled, without - * setting this bit, authentication will fail and may - * crash. - */ - /* Check MMU enabled */ - if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) { - if (is_mx6dq()) { - /* - * This won't work on Rev 1.0.0 of - * i.MX6Q/D, since their ROM doesn't - * do cache flushes. don't think any - * exist, so we ignore them. - */ - if (!is_mx6dqp()) - writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); - } else if (is_mx6sdl()) { - writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); - } else if (is_mx6sl()) { - writel(1, MX6SL_PU_IROM_MMU_EN_VAR); - } + /* + * If the MMU is enabled, we have to notify the ROM + * code, or it won't flush the caches when needed. + * This is done, by setting the "pu_irom_mmu_enabled" + * word to 1. You can find its address by looking in + * the ROM map. This is critical for + * authenticate_image(). If MMU is enabled, without + * setting this bit, authentication will fail and may + * crash. + */ + /* Check MMU enabled */ + if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) { + if (is_mx6dq()) { + /* + * This won't work on Rev 1.0.0 of + * i.MX6Q/D, since their ROM doesn't + * do cache flushes. don't think any + * exist, so we ignore them. + */ + if (!is_mx6dqp()) + writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); + } else if (is_mx6sdl()) { + writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); + } else if (is_mx6sl()) { + writel(1, MX6SL_PU_IROM_MMU_EN_VAR); } + } - load_addr = (uint32_t)hab_rvt_authenticate_image( - HAB_CID_UBOOT, - ivt_offset, (void **)&start, - (size_t *)&bytes, NULL); - if (hab_rvt_exit() != HAB_SUCCESS) { - puts("hab exit function fail\n"); - load_addr = 0; - } - } else { - puts("hab entry function fail\n"); + load_addr = (uint32_t)hab_rvt_authenticate_image( + HAB_CID_UBOOT, + ivt_offset, (void **)&start, + (size_t *)&bytes, NULL); + if (hab_rvt_exit() != HAB_SUCCESS) { + puts("hab exit function fail\n"); + load_addr = 0; } +hab_caam_clock_disable: hab_caam_clock_enable(0); #if !defined(CONFIG_SPL_BUILD) -- cgit From 191d8bd509023ccea9cff3129dc8ae76fe297b2d Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:39:59 +0000 Subject: arm: imx: hab: Move IVT_SIZE to hab.h The size of the IVT header should be defined in hab.h move it there now. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 2 ++ arch/arm/mach-imx/hab.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 1b7a5e4440..3c19d2e94f 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -143,6 +143,8 @@ typedef void hapi_clock_init_t(void); #define HAB_CID_ROM 0 /**< ROM Caller ID */ #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/ +#define IVT_SIZE 0x20 + /* ----------- end of HAB API updates ------------*/ int authenticate_image(uint32_t ddr_start, uint32_t image_size); diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index f878b7bf9d..6367562be8 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -70,7 +70,6 @@ ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ ) -#define IVT_SIZE 0x20 #define ALIGN_SIZE 0x1000 #define CSF_PAD_SIZE 0x2000 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 -- cgit From 08a81cad2f7802166ab6adc349b3e247aa4517c7 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:00 +0000 Subject: arm: imx: hab: Move CSF_PAD_SIZE to hab.h CSF_PAD_SIZE should be defined in hab.h, move it to that location now. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 1 + arch/arm/mach-imx/hab.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 3c19d2e94f..91dda4269e 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -144,6 +144,7 @@ typedef void hapi_clock_init_t(void); #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/ #define IVT_SIZE 0x20 +#define CSF_PAD_SIZE 0x2000 /* ----------- end of HAB API updates ------------*/ diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 6367562be8..039a017314 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -71,7 +71,6 @@ ) #define ALIGN_SIZE 0x1000 -#define CSF_PAD_SIZE 0x2000 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0 #define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18 -- cgit From c5800b254159c58773004eae1b58502eea4d1f6b Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:01 +0000 Subject: arm: imx: hab: Fix authenticate_image input parameters u-boot command "hab_auth_img" tells a user that it takes - addr - image hex address - offset - hex offset of IVT in the image but in fact the callback hab_auth_img makes to authenticate_image treats the second 'offset' parameter as an image length. Furthermore existing code requires the IVT header to be appended to the end of the image which is not actually a requirement of HABv4. This patch fixes this situation by 1: Adding a new parameter to hab_auth_img - addr : image hex address - length : total length of the image - offset : offset of IVT from addr 2: Updates the existing call into authenticate_image() in arch/arm/mach-imx/spl.c:jump_to_image_no_args() to pass addr, length and IVT offset respectively. This allows then hab_auth_img to actually operate the way it was specified in the help text and should still allow existing code to work. It has the added advantage that the IVT header doesn't have to be appended to an image given to HAB - it can be prepended for example. Note prepending the IVT is what u-boot will do when making an IVT for the BootROM. It should be possible for u-boot properly authenticate images made by mkimage via HAB. This patch is the first step in making that happen subsequent patches will focus on removing hard-coded offsets to the IVT, which again is not mandated to live at the end of a .imx image. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 3 +- arch/arm/mach-imx/hab.c | 73 +++++++++++-------------------------- arch/arm/mach-imx/spl.c | 35 +++++++++++++++++- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 91dda4269e..b2a80319eb 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -148,6 +148,7 @@ typedef void hapi_clock_init_t(void); /* ----------- end of HAB API updates ------------*/ -int authenticate_image(uint32_t ddr_start, uint32_t image_size); +int authenticate_image(uint32_t ddr_start, uint32_t image_size, + uint32_t ivt_offset); #endif diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 039a017314..2a40d065dd 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -78,37 +78,6 @@ (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \ (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2)) -/* - * +------------+ 0x0 (DDR_UIMAGE_START) - - * | Header | | - * +------------+ 0x40 | - * | | | - * | | | - * | | | - * | | | - * | Image Data | | - * . | | - * . | > Stuff to be authenticated ----+ - * . | | | - * | | | | - * | | | | - * +------------+ | | - * | | | | - * | Fill Data | | | - * | | | | - * +------------+ Align to ALIGN_SIZE | | - * | IVT | | | - * +------------+ + IVT_SIZE - | - * | | | - * | CSF DATA | <---------------------------------------------------------+ - * | | - * +------------+ - * | | - * | Fill Data | - * | | - * +------------+ + CSF_PAD_SIZE - */ - static bool is_hab_enabled(void); #if !defined(CONFIG_SPL_BUILD) @@ -361,20 +330,22 @@ int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - ulong addr, ivt_offset; + ulong addr, length, ivt_offset; int rcode = 0; - if (argc < 3) + if (argc < 4) return CMD_RET_USAGE; addr = simple_strtoul(argv[1], NULL, 16); - ivt_offset = simple_strtoul(argv[2], NULL, 16); + length = simple_strtoul(argv[2], NULL, 16); + ivt_offset = simple_strtoul(argv[3], NULL, 16); - rcode = authenticate_image(addr, ivt_offset); + rcode = authenticate_image(addr, length, ivt_offset); if (rcode == 0) rcode = CMD_RET_SUCCESS; else rcode = CMD_RET_FAILURE; + return rcode; } @@ -385,10 +356,11 @@ U_BOOT_CMD( ); U_BOOT_CMD( - hab_auth_img, 3, 0, do_authenticate_image, + hab_auth_img, 4, 0, do_authenticate_image, "authenticate image via HAB", - "addr ivt_offset\n" + "addr length ivt_offset\n" "addr - image hex address\n" + "length - image hex length\n" "ivt_offset - hex offset of IVT in the image" ); @@ -411,11 +383,12 @@ static bool is_hab_enabled(void) return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT; } -int authenticate_image(uint32_t ddr_start, uint32_t image_size) +int authenticate_image(uint32_t ddr_start, uint32_t image_size, + uint32_t ivt_offset) { uint32_t load_addr = 0; size_t bytes; - ptrdiff_t ivt_offset = 0; + uint32_t ivt_addr = 0; int result = 1; ulong start; hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; @@ -441,24 +414,18 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) goto hab_caam_clock_disable; } - /* If not already aligned, Align to ALIGN_SIZE */ - ivt_offset = (image_size + ALIGN_SIZE - 1) & - ~(ALIGN_SIZE - 1); - + /* Calculate IVT address header */ + ivt_addr = ddr_start + ivt_offset; start = ddr_start; - bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; + bytes = image_size; #ifdef DEBUG - printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", - ivt_offset, ddr_start + ivt_offset); + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); puts("Dumping IVT\n"); - print_buffer(ddr_start + ivt_offset, - (void *)(ddr_start + ivt_offset), - 4, 0x8, 0); + print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0); puts("Dumping CSF Header\n"); - print_buffer(ddr_start + ivt_offset + IVT_SIZE, - (void *)(ddr_start + ivt_offset + IVT_SIZE), - 4, 0x10, 0); + print_buffer(ivt_addr + IVT_SIZE, (void *)(ivt_addr + IVT_SIZE), 4, + 0x10, 0); #if !defined(CONFIG_SPL_BUILD) get_hab_status(); @@ -468,6 +435,8 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size) printf("\tivt_offset = 0x%x\n", ivt_offset); printf("\tstart = 0x%08lx\n", start); printf("\tbytes = 0x%x\n", bytes); +#else + (void)ivt_addr; #endif /* * If the MMU is enabled, we have to notify the ROM diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 31b4b0fcfc..141579dbad 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -155,9 +155,41 @@ u32 spl_boot_mode(const u32 boot_device) #if defined(CONFIG_SECURE_BOOT) +/* + * +------------+ 0x0 (DDR_UIMAGE_START) - + * | Header | | + * +------------+ 0x40 | + * | | | + * | | | + * | | | + * | | | + * | Image Data | | + * . | | + * . | > Stuff to be authenticated ----+ + * . | | | + * | | | | + * | | | | + * +------------+ | | + * | | | | + * | Fill Data | | | + * | | | | + * +------------+ Align to ALIGN_SIZE | | + * | IVT | | | + * +------------+ + IVT_SIZE - | + * | | | + * | CSF DATA | <---------------------------------------------------------+ + * | | + * +------------+ + * | | + * | Fill Data | + * | | + * +------------+ + CSF_PAD_SIZE + */ + __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(void); + uint32_t offset; image_entry_noargs_t image_entry = (image_entry_noargs_t)(unsigned long)spl_image->entry_point; @@ -166,8 +198,9 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) /* HAB looks for the CSF at the end of the authenticated data therefore, * we need to subtract the size of the CSF from the actual filesize */ + offset = spl_image->size - CONFIG_CSF_SIZE; if (!authenticate_image(spl_image->load_addr, - spl_image->size - CONFIG_CSF_SIZE)) { + offset + IVT_SIZE + CSF_PAD_SIZE, offset)) { image_entry(); } else { puts("spl: ERROR: image authentication unsuccessful\n"); -- cgit From cd2d46003ce14b21cc323a075caf90012f4cd83d Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:02 +0000 Subject: arm: imx: hab: Add IVT header definitions The various i.MX BootROMs containing the High Assurance Boot (HAB) block rely on a data structure called the Image Vector Table (IVT) to describe to the BootROM where to locate various data-structures used by HAB during authentication. This patch adds a definition of the IVT header for use in later patches, where we will break the current incorrect dependence on fixed offsets in favour of an IVT described parsing of incoming binaries. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index b2a80319eb..28cde38462 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -10,6 +10,34 @@ #include +/* + * IVT header definitions + * Security Reference Manual for i.MX 7Dual and 7Solo Applications Processors, + * Rev. 0, 03/2017 + * Section : 6.7.1.1 + */ +#define IVT_HEADER_MAGIC 0xD1 +#define IVT_TOTAL_LENGTH 0x20 +#define IVT_HEADER_V1 0x40 +#define IVT_HEADER_V2 0x41 + +struct ivt_header { + uint8_t magic; + uint16_t length; + uint8_t version; +} __attribute__((packed)); + +struct ivt { + struct ivt_header hdr; /* IVT header above */ + uint32_t entry; /* Absolute address of first instruction */ + uint32_t reserved1; /* Reserved should be zero */ + uint32_t dcd; /* Absolute address of the image DCD */ + uint32_t boot; /* Absolute address of the boot data */ + uint32_t self; /* Absolute address of the IVT */ + uint32_t csf; /* Absolute address of the CSF */ + uint32_t reserved2; /* Reserved should be zero */ +}; + /* -------- start of HAB API updates ------------*/ /* The following are taken from HAB4 SIS */ -- cgit From 49b6d058826ec3c588897124601f434072de07cd Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:03 +0000 Subject: arm: imx: hab: Add IVT header verification The IVT header contains a magic number, fixed length and one of two version identifiers. Validate these settings before doing anything with a putative IVT binary. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 2a40d065dd..998d253f2c 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -80,6 +80,31 @@ static bool is_hab_enabled(void); +static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr) +{ + printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str, + ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version); + + return 1; +} + +static int verify_ivt_header(struct ivt_header *ivt_hdr) +{ + int result = 0; + + if (ivt_hdr->magic != IVT_HEADER_MAGIC) + result = ivt_header_error("bad magic", ivt_hdr); + + if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH) + result = ivt_header_error("bad length", ivt_hdr); + + if (ivt_hdr->version != IVT_HEADER_V1 && + ivt_hdr->version != IVT_HEADER_V2) + result = ivt_header_error("bad version", ivt_hdr); + + return result; +} + #if !defined(CONFIG_SPL_BUILD) #define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */ @@ -394,6 +419,8 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; hab_rvt_entry_t *hab_rvt_entry; hab_rvt_exit_t *hab_rvt_exit; + struct ivt *ivt; + struct ivt_header *ivt_hdr; hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; hab_rvt_entry = hab_rvt_entry_p; @@ -416,6 +443,13 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, /* Calculate IVT address header */ ivt_addr = ddr_start + ivt_offset; + ivt = (struct ivt *)ivt_addr; + ivt_hdr = &ivt->hdr; + + /* Verify IVT header bugging out on error */ + if (verify_ivt_header(ivt_hdr)) + goto hab_caam_clock_disable; + start = ddr_start; bytes = image_size; #ifdef DEBUG @@ -435,8 +469,6 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, printf("\tivt_offset = 0x%x\n", ivt_offset); printf("\tstart = 0x%08lx\n", start); printf("\tbytes = 0x%x\n", bytes); -#else - (void)ivt_addr; #endif /* * If the MMU is enabled, we have to notify the ROM -- cgit From e59eb9e00fcc97f566d38adb0d3c33480a9d0178 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:04 +0000 Subject: arm: imx: hab: Verify IVT self matches calculated address The IVT is a self-describing structure which contains a self field. The self field is the absolute physical base address the IVT ought to be at in memory. Use the IVT self field to validate the calculated ivt_addr bugging out if the two values differ. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 998d253f2c..39f8f2de59 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -450,6 +450,13 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, if (verify_ivt_header(ivt_hdr)) goto hab_caam_clock_disable; + /* Verify IVT body */ + if (ivt->self != ivt_addr) { + printf("ivt->self 0x%08x pointer is 0x%08x\n", + ivt->self, ivt_addr); + goto hab_caam_clock_disable; + } + start = ddr_start; bytes = image_size; #ifdef DEBUG -- cgit From 04099e9ced6421940248d5357786901bb89f4ce4 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:05 +0000 Subject: arm: imx: hab: Only call ROM once headers are verified Previous patches added IVT header verification steps. We shouldn't call hab_rvt_entry() until we have done the basic header verification steps. This patch changes the time we make the hab_rvt_entry() call so that it only takes place if we are happy with the IVT header sanity checks. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 39f8f2de59..a8e3e79c3b 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -436,11 +436,6 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, hab_caam_clock_enable(1); - if (hab_rvt_entry() != HAB_SUCCESS) { - puts("hab entry function fail\n"); - goto hab_caam_clock_disable; - } - /* Calculate IVT address header */ ivt_addr = ddr_start + ivt_offset; ivt = (struct ivt *)ivt_addr; @@ -459,6 +454,12 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, start = ddr_start; bytes = image_size; + + if (hab_rvt_entry() != HAB_SUCCESS) { + puts("hab entry function fail\n"); + goto hab_caam_clock_disable; + } + #ifdef DEBUG printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); puts("Dumping IVT\n"); -- cgit From fd15fe5f84de3d0a46a548adc0ae363207d984ed Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:06 +0000 Subject: arm: imx: hab: Print CSF based on IVT descriptor The IVT gives the absolute address of the CSF. There is no requirement for the CSF to be located adjacent to the IVT so lets use the address provided in the IVT header instead of the hard-coded fixed CSF offset currently in place. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index a8e3e79c3b..229c723ba2 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -466,8 +466,7 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0); puts("Dumping CSF Header\n"); - print_buffer(ivt_addr + IVT_SIZE, (void *)(ivt_addr + IVT_SIZE), 4, - 0x10, 0); + print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0); #if !defined(CONFIG_SPL_BUILD) get_hab_status(); -- cgit From 824ef302f362c3350fa17c8a006300b159430a16 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:07 +0000 Subject: arm: imx: hab: Print additional IVT elements during debug This patch enables printout of the IVT entry, dcd and csf data fields. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 229c723ba2..364bd6b5c3 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -462,6 +462,8 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, #ifdef DEBUG printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); + printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry, + ivt->dcd, ivt->csf); puts("Dumping IVT\n"); print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0); -- cgit From 1addedadc4e9a7ca05a985fb6bf9b07c6458ff27 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:08 +0000 Subject: arm: imx: hab: Define rvt_check_target() The hab_rvt_check_target() callback according to the HABv4 documentation: "This function reports whether or not a given target region is allowed for either peripheral configuration or image loading in memory. It is intended for use by post-ROM boot stage components, via the ROM Vector Table, in order to avoid configuring security-sensitive peripherals, or loading images over sensitive memory regions or outside recognized memory devices in the address map." It is a useful function to support as a precursor to calling into authenticate_image() to validate the target memory region is good. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 28cde38462..14e12203c2 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -113,6 +113,12 @@ enum hab_context { HAB_CTX_MAX }; +enum hab_target { + HAB_TGT_MEMORY = 0x0f, + HAB_TGT_PERIPHERAL = 0xf0, + HAB_TGT_ANY = 0x55, +}; + struct imx_sec_config_fuse_t { int bank; int word; @@ -132,6 +138,8 @@ typedef enum hab_status hab_rvt_entry_t(void); typedef enum hab_status hab_rvt_exit_t(void); typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t, void **, size_t *, hab_loader_callback_f_t); +typedef enum hab_status hab_rvt_check_target_t(enum hab_target, const void *, + size_t); typedef void hapi_clock_init_t(void); #define HAB_ENG_ANY 0x00 /* Select first compatible engine */ @@ -158,6 +166,7 @@ typedef void hapi_clock_init_t(void); #define HAB_RVT_ENTRY (*(uint32_t *)(HAB_RVT_BASE + 0x04)) #define HAB_RVT_EXIT (*(uint32_t *)(HAB_RVT_BASE + 0x08)) +#define HAB_RVT_CHECK_TARGET (*(uint32_t *)(HAB_RVT_BASE + 0x0C)) #define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)(HAB_RVT_BASE + 0x10)) #define HAB_RVT_REPORT_EVENT (*(uint32_t *)(HAB_RVT_BASE + 0x20)) #define HAB_RVT_REPORT_STATUS (*(uint32_t *)(HAB_RVT_BASE + 0x24)) -- cgit From c0a55b7344d4ed0b003e3f9696663539f50aaacb Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:09 +0000 Subject: arm: imx: hab: Implement hab_rvt_check_target This patch implements the basic callback hooks for hab_rvt_check_target() for BootROM code using the older BootROM address layout - in my test case the i.MX7. Code based on new BootROM callbacks will just have HAB_SUCCESS as a result code. Adding support for the new BootROM callbacks is a TODO. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 364bd6b5c3..2a18ea2da5 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -70,6 +70,24 @@ ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ ) +static inline enum hab_status hab_rvt_check_target_new(enum hab_target target, + const void *start, + size_t bytes) +{ + return HAB_SUCCESS; +} + +#define hab_rvt_check_target_p \ +( \ + (is_mx6dqp()) ? \ + ((hab_rvt_check_target_t *)hab_rvt_check_target_new) : \ + (is_mx6dq() && (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_check_target_t *)hab_rvt_check_target_new) : \ + (is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_check_target_t *)hab_rvt_check_target_new) : \ + ((hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET) \ +) + #define ALIGN_SIZE 0x1000 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0 -- cgit From b7c3cae7d35f003b8f4d15e8597eb638e5302796 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:10 +0000 Subject: arm: imx: hab: Add a hab_rvt_check_target to image auth Add a hab_rvt_check_target() step to authenticate_image() as a sanity check for the target memory region authenticate_image() will run over, prior to making the BootROM authentication callback itself. This check is recommended by the HAB documentation so it makes sense to adhere to the guidance and perform that check as directed. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 2a18ea2da5..079423a1e3 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -437,12 +437,15 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; hab_rvt_entry_t *hab_rvt_entry; hab_rvt_exit_t *hab_rvt_exit; + hab_rvt_check_target_t *hab_rvt_check_target; struct ivt *ivt; struct ivt_header *ivt_hdr; + enum hab_status status; hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; hab_rvt_entry = hab_rvt_entry_p; hab_rvt_exit = hab_rvt_exit_p; + hab_rvt_check_target = hab_rvt_check_target_p; if (!is_hab_enabled()) { puts("hab fuse not enabled\n"); @@ -478,6 +481,12 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, goto hab_caam_clock_disable; } + status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes); + if (status != HAB_SUCCESS) { + printf("HAB check target 0x%08x-0x%08x fail\n", + ddr_start, ddr_start + bytes); + goto hab_caam_clock_disable; + } #ifdef DEBUG printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry, -- cgit From 2c6c68d282b84f8766917bd72db17bfb223f2cca Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:11 +0000 Subject: arm: imx: hab: Print HAB event log only after calling ROM The current flow of authenticate_image() will print the HAB event log even if we reject an element of the IVT header before ever calling into the ROM. This can be confusing. This patch changes the flow of the code so that the HAB event log is only printed out if we have called into the ROM and received some sort of status code. Signed-off-by: Bryan O'Donoghue Suggested-by: Cc: Breno Matheus Lima Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 079423a1e3..3ae88a483d 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -478,14 +478,14 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, if (hab_rvt_entry() != HAB_SUCCESS) { puts("hab entry function fail\n"); - goto hab_caam_clock_disable; + goto hab_exit_failure_print_status; } status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes); if (status != HAB_SUCCESS) { printf("HAB check target 0x%08x-0x%08x fail\n", ddr_start, ddr_start + bytes); - goto hab_caam_clock_disable; + goto hab_exit_failure_print_status; } #ifdef DEBUG printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); @@ -543,12 +543,14 @@ int authenticate_image(uint32_t ddr_start, uint32_t image_size, load_addr = 0; } -hab_caam_clock_disable: - hab_caam_clock_enable(0); - +hab_exit_failure_print_status: #if !defined(CONFIG_SPL_BUILD) get_hab_status(); #endif + +hab_caam_clock_disable: + hab_caam_clock_enable(0); + if (load_addr != 0) result = 0; -- cgit From 58bebfb753e5ae0a87fff59fa44afae0c1b0cabf Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:12 +0000 Subject: arm: imx: hab: Make internal functions and data static There is no need to export these functions and data structures externally. Make them all static now. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 159 +++++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 3ae88a483d..ec85548088 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -135,73 +135,81 @@ struct record { bool any_rec_flag; }; -char *rsn_str[] = {"RSN = HAB_RSN_ANY (0x00)\n", - "RSN = HAB_ENG_FAIL (0x30)\n", - "RSN = HAB_INV_ADDRESS (0x22)\n", - "RSN = HAB_INV_ASSERTION (0x0C)\n", - "RSN = HAB_INV_CALL (0x28)\n", - "RSN = HAB_INV_CERTIFICATE (0x21)\n", - "RSN = HAB_INV_COMMAND (0x06)\n", - "RSN = HAB_INV_CSF (0x11)\n", - "RSN = HAB_INV_DCD (0x27)\n", - "RSN = HAB_INV_INDEX (0x0F)\n", - "RSN = HAB_INV_IVT (0x05)\n", - "RSN = HAB_INV_KEY (0x1D)\n", - "RSN = HAB_INV_RETURN (0x1E)\n", - "RSN = HAB_INV_SIGNATURE (0x18)\n", - "RSN = HAB_INV_SIZE (0x17)\n", - "RSN = HAB_MEM_FAIL (0x2E)\n", - "RSN = HAB_OVR_COUNT (0x2B)\n", - "RSN = HAB_OVR_STORAGE (0x2D)\n", - "RSN = HAB_UNS_ALGORITHM (0x12)\n", - "RSN = HAB_UNS_COMMAND (0x03)\n", - "RSN = HAB_UNS_ENGINE (0x0A)\n", - "RSN = HAB_UNS_ITEM (0x24)\n", - "RSN = HAB_UNS_KEY (0x1B)\n", - "RSN = HAB_UNS_PROTOCOL (0x14)\n", - "RSN = HAB_UNS_STATE (0x09)\n", - "RSN = INVALID\n", - NULL}; - -char *sts_str[] = {"STS = HAB_SUCCESS (0xF0)\n", - "STS = HAB_FAILURE (0x33)\n", - "STS = HAB_WARNING (0x69)\n", - "STS = INVALID\n", - NULL}; - -char *eng_str[] = {"ENG = HAB_ENG_ANY (0x00)\n", - "ENG = HAB_ENG_SCC (0x03)\n", - "ENG = HAB_ENG_RTIC (0x05)\n", - "ENG = HAB_ENG_SAHARA (0x06)\n", - "ENG = HAB_ENG_CSU (0x0A)\n", - "ENG = HAB_ENG_SRTC (0x0C)\n", - "ENG = HAB_ENG_DCP (0x1B)\n", - "ENG = HAB_ENG_CAAM (0x1D)\n", - "ENG = HAB_ENG_SNVS (0x1E)\n", - "ENG = HAB_ENG_OCOTP (0x21)\n", - "ENG = HAB_ENG_DTCP (0x22)\n", - "ENG = HAB_ENG_ROM (0x36)\n", - "ENG = HAB_ENG_HDCP (0x24)\n", - "ENG = HAB_ENG_RTL (0x77)\n", - "ENG = HAB_ENG_SW (0xFF)\n", - "ENG = INVALID\n", - NULL}; - -char *ctx_str[] = {"CTX = HAB_CTX_ANY(0x00)\n", - "CTX = HAB_CTX_FAB (0xFF)\n", - "CTX = HAB_CTX_ENTRY (0xE1)\n", - "CTX = HAB_CTX_TARGET (0x33)\n", - "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n", - "CTX = HAB_CTX_DCD (0xDD)\n", - "CTX = HAB_CTX_CSF (0xCF)\n", - "CTX = HAB_CTX_COMMAND (0xC0)\n", - "CTX = HAB_CTX_AUT_DAT (0xDB)\n", - "CTX = HAB_CTX_ASSERT (0xA0)\n", - "CTX = HAB_CTX_EXIT (0xEE)\n", - "CTX = INVALID\n", - NULL}; - -uint8_t hab_statuses[5] = { +static char *rsn_str[] = { + "RSN = HAB_RSN_ANY (0x00)\n", + "RSN = HAB_ENG_FAIL (0x30)\n", + "RSN = HAB_INV_ADDRESS (0x22)\n", + "RSN = HAB_INV_ASSERTION (0x0C)\n", + "RSN = HAB_INV_CALL (0x28)\n", + "RSN = HAB_INV_CERTIFICATE (0x21)\n", + "RSN = HAB_INV_COMMAND (0x06)\n", + "RSN = HAB_INV_CSF (0x11)\n", + "RSN = HAB_INV_DCD (0x27)\n", + "RSN = HAB_INV_INDEX (0x0F)\n", + "RSN = HAB_INV_IVT (0x05)\n", + "RSN = HAB_INV_KEY (0x1D)\n", + "RSN = HAB_INV_RETURN (0x1E)\n", + "RSN = HAB_INV_SIGNATURE (0x18)\n", + "RSN = HAB_INV_SIZE (0x17)\n", + "RSN = HAB_MEM_FAIL (0x2E)\n", + "RSN = HAB_OVR_COUNT (0x2B)\n", + "RSN = HAB_OVR_STORAGE (0x2D)\n", + "RSN = HAB_UNS_ALGORITHM (0x12)\n", + "RSN = HAB_UNS_COMMAND (0x03)\n", + "RSN = HAB_UNS_ENGINE (0x0A)\n", + "RSN = HAB_UNS_ITEM (0x24)\n", + "RSN = HAB_UNS_KEY (0x1B)\n", + "RSN = HAB_UNS_PROTOCOL (0x14)\n", + "RSN = HAB_UNS_STATE (0x09)\n", + "RSN = INVALID\n", + NULL +}; + +static char *sts_str[] = { + "STS = HAB_SUCCESS (0xF0)\n", + "STS = HAB_FAILURE (0x33)\n", + "STS = HAB_WARNING (0x69)\n", + "STS = INVALID\n", + NULL +}; + +static char *eng_str[] = { + "ENG = HAB_ENG_ANY (0x00)\n", + "ENG = HAB_ENG_SCC (0x03)\n", + "ENG = HAB_ENG_RTIC (0x05)\n", + "ENG = HAB_ENG_SAHARA (0x06)\n", + "ENG = HAB_ENG_CSU (0x0A)\n", + "ENG = HAB_ENG_SRTC (0x0C)\n", + "ENG = HAB_ENG_DCP (0x1B)\n", + "ENG = HAB_ENG_CAAM (0x1D)\n", + "ENG = HAB_ENG_SNVS (0x1E)\n", + "ENG = HAB_ENG_OCOTP (0x21)\n", + "ENG = HAB_ENG_DTCP (0x22)\n", + "ENG = HAB_ENG_ROM (0x36)\n", + "ENG = HAB_ENG_HDCP (0x24)\n", + "ENG = HAB_ENG_RTL (0x77)\n", + "ENG = HAB_ENG_SW (0xFF)\n", + "ENG = INVALID\n", + NULL +}; + +static char *ctx_str[] = { + "CTX = HAB_CTX_ANY(0x00)\n", + "CTX = HAB_CTX_FAB (0xFF)\n", + "CTX = HAB_CTX_ENTRY (0xE1)\n", + "CTX = HAB_CTX_TARGET (0x33)\n", + "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n", + "CTX = HAB_CTX_DCD (0xDD)\n", + "CTX = HAB_CTX_CSF (0xCF)\n", + "CTX = HAB_CTX_COMMAND (0xC0)\n", + "CTX = HAB_CTX_AUT_DAT (0xDB)\n", + "CTX = HAB_CTX_ASSERT (0xA0)\n", + "CTX = HAB_CTX_EXIT (0xEE)\n", + "CTX = INVALID\n", + NULL +}; + +static uint8_t hab_statuses[5] = { HAB_STS_ANY, HAB_FAILURE, HAB_WARNING, @@ -209,7 +217,7 @@ uint8_t hab_statuses[5] = { -1 }; -uint8_t hab_reasons[26] = { +static uint8_t hab_reasons[26] = { HAB_RSN_ANY, HAB_ENG_FAIL, HAB_INV_ADDRESS, @@ -238,7 +246,7 @@ uint8_t hab_reasons[26] = { -1 }; -uint8_t hab_contexts[12] = { +static uint8_t hab_contexts[12] = { HAB_CTX_ANY, HAB_CTX_FAB, HAB_CTX_ENTRY, @@ -253,7 +261,7 @@ uint8_t hab_contexts[12] = { -1 }; -uint8_t hab_engines[16] = { +static uint8_t hab_engines[16] = { HAB_ENG_ANY, HAB_ENG_SCC, HAB_ENG_RTIC, @@ -284,7 +292,7 @@ static inline uint8_t get_idx(uint8_t *list, uint8_t tgt) return -1; } -void process_event_record(uint8_t *event_data, size_t bytes) +static void process_event_record(uint8_t *event_data, size_t bytes) { struct record *rec = (struct record *)event_data; @@ -294,7 +302,7 @@ void process_event_record(uint8_t *event_data, size_t bytes) printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]); } -void display_event(uint8_t *event_data, size_t bytes) +static void display_event(uint8_t *event_data, size_t bytes) { uint32_t i; @@ -313,7 +321,7 @@ void display_event(uint8_t *event_data, size_t bytes) process_event_record(event_data, bytes); } -int get_hab_status(void) +static int get_hab_status(void) { uint32_t index = 0; /* Loop index */ uint8_t event_data[128]; /* Event data buffer */ @@ -358,7 +366,8 @@ int get_hab_status(void) return 0; } -int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { if ((argc != 1)) { cmd_usage(cmdtp); @@ -371,7 +380,7 @@ int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) + char * const argv[]) { ulong addr, length, ivt_offset; int rcode = 0; -- cgit From 57f65486068e807c4d39309009930451f7cf9604 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:13 +0000 Subject: arm: imx: hab: Prefix authenticate_image with imx_hab Tidy up the HAB namespace a bit by prefixing external functions with imx_hab. All external facing functions past this point will be prefixed in the same way to make the fact we are doing IMX HAB activities clear from reading the code. authenticate_image() could mean anything imx_hab_authenticate_image() is on the other hand very explicit. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 4 ++-- arch/arm/mach-imx/hab.c | 6 +++--- arch/arm/mach-imx/spl.c | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 14e12203c2..98bc1bdc65 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -185,7 +185,7 @@ typedef void hapi_clock_init_t(void); /* ----------- end of HAB API updates ------------*/ -int authenticate_image(uint32_t ddr_start, uint32_t image_size, - uint32_t ivt_offset); +int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, + uint32_t ivt_offset); #endif diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index ec85548088..7c2f82897b 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -392,7 +392,7 @@ static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, length = simple_strtoul(argv[2], NULL, 16); ivt_offset = simple_strtoul(argv[3], NULL, 16); - rcode = authenticate_image(addr, length, ivt_offset); + rcode = imx_hab_authenticate_image(addr, length, ivt_offset); if (rcode == 0) rcode = CMD_RET_SUCCESS; else @@ -435,8 +435,8 @@ static bool is_hab_enabled(void) return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT; } -int authenticate_image(uint32_t ddr_start, uint32_t image_size, - uint32_t ivt_offset) +int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, + uint32_t ivt_offset) { uint32_t load_addr = 0; size_t bytes; diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 141579dbad..6c16872f59 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -199,8 +199,9 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) /* HAB looks for the CSF at the end of the authenticated data therefore, * we need to subtract the size of the CSF from the actual filesize */ offset = spl_image->size - CONFIG_CSF_SIZE; - if (!authenticate_image(spl_image->load_addr, - offset + IVT_SIZE + CSF_PAD_SIZE, offset)) { + if (!imx_hab_authenticate_image(spl_image->load_addr, + offset + IVT_SIZE + CSF_PAD_SIZE, + offset)) { image_entry(); } else { puts("spl: ERROR: image authentication unsuccessful\n"); -- cgit From e5b30e4ac19b745ef5ed75813d48fa78d7c579f6 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:14 +0000 Subject: arm: imx: hab: Rename is_hab_enabled imx_hab_is_enabled Understanding if the HAB is enabled is something that we want to interrogate and report on outside of the HAB layer. First step to that is renaming the relevant function to match the previously introduced external naming convention imx_hab_function() The name imx_hab_is_hab_enabled() is a tautology. A more logical name is imx_hab_is_enabled(). Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 7c2f82897b..d917ac3af9 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -96,7 +96,7 @@ static inline enum hab_status hab_rvt_check_target_new(enum hab_target target, (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \ (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2)) -static bool is_hab_enabled(void); +static bool imx_hab_is_enabled(void); static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr) { @@ -334,7 +334,7 @@ static int get_hab_status(void) hab_rvt_report_event = hab_rvt_report_event_p; hab_rvt_report_status = hab_rvt_report_status_p; - if (is_hab_enabled()) + if (imx_hab_is_enabled()) puts("\nSecure boot enabled\n"); else puts("\nSecure boot disabled\n"); @@ -419,7 +419,7 @@ U_BOOT_CMD( #endif /* !defined(CONFIG_SPL_BUILD) */ -static bool is_hab_enabled(void) +static bool imx_hab_is_enabled(void) { struct imx_sec_config_fuse_t *fuse = (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; @@ -456,7 +456,7 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, hab_rvt_exit = hab_rvt_exit_p; hab_rvt_check_target = hab_rvt_check_target_p; - if (!is_hab_enabled()) { + if (!imx_hab_is_enabled()) { puts("hab fuse not enabled\n"); return result; } -- cgit From 4467ae6c28aa7eef84d5784f56234472a015d5e2 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:15 +0000 Subject: arm: imx: hab: Make authenticate_image() return zero on open boards The BootROM will not successfully process a HAB image passed by u-boot unless the board has been set into locked mode. Some of the existing usages of authenticate_image() expect and rely on unlocked boards doing the following 1. Not calling into the BootROM authenticate_image() callback 2. Returning a pass status for authenticate_image() calls anyway A previous patch removed the necessity to call into imx_hab_is_enabled() twice. This patch ensures the reliance on authenticate_image() returning zero is maintained. Signed-off-by: Bryan O'Donoghue Suggested-by: Breno Matheus Lima Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Tested-by: Breno Lima --- arch/arm/mach-imx/hab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index d917ac3af9..3b19a7e573 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -458,7 +458,7 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, if (!imx_hab_is_enabled()) { puts("hab fuse not enabled\n"); - return result; + return 0; } printf("\nAuthenticate image from DDR location 0x%x...\n", -- cgit From 07eefaf16e2a7aec35fa3ae8c17c5492cc0af524 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:16 +0000 Subject: arm: imx: hab: Make imx_hab_is_enabled global It will be helpful to boot commands to know if the HAB is enabled. Export imx_hab_is_enabled() now to facilitate further work with this data-point in a secure-boot context. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 1 + arch/arm/mach-imx/hab.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 98bc1bdc65..5c13aff1d5 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -187,5 +187,6 @@ typedef void hapi_clock_init_t(void); int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, uint32_t ivt_offset); +bool imx_hab_is_enabled(void); #endif diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 3b19a7e573..d1c5f69681 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -96,8 +96,6 @@ static inline enum hab_status hab_rvt_check_target_new(enum hab_target target, (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \ (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2)) -static bool imx_hab_is_enabled(void); - static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr) { printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str, @@ -419,7 +417,7 @@ U_BOOT_CMD( #endif /* !defined(CONFIG_SPL_BUILD) */ -static bool imx_hab_is_enabled(void) +bool imx_hab_is_enabled(void) { struct imx_sec_config_fuse_t *fuse = (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; -- cgit From aeae70fac5c9ca9b082222da513d5f287bda73c4 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:17 +0000 Subject: arm: imx: hab: Define rvt_failsafe() The hab_rvt_failsafe() callback according to the HABv4 documentation: "This function provides a safe path when image authentication has failed and all possible boot paths have been exhausted. It is intended for use by post-ROM boot stage components, via the ROM Vector Table." Once invoked the part will drop down to its BootROM USB recovery mode. Should it be the case that the part is in secure boot mode - only an appropriately signed binary will be accepted by the ROM and subsequently executed. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/include/asm/mach-imx/hab.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h index 5c13aff1d5..a0cb19db2f 100644 --- a/arch/arm/include/asm/mach-imx/hab.h +++ b/arch/arm/include/asm/mach-imx/hab.h @@ -140,6 +140,7 @@ typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t, void **, size_t *, hab_loader_callback_f_t); typedef enum hab_status hab_rvt_check_target_t(enum hab_target, const void *, size_t); +typedef void hab_rvt_failsafe_t(void); typedef void hapi_clock_init_t(void); #define HAB_ENG_ANY 0x00 /* Select first compatible engine */ @@ -170,6 +171,7 @@ typedef void hapi_clock_init_t(void); #define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)(HAB_RVT_BASE + 0x10)) #define HAB_RVT_REPORT_EVENT (*(uint32_t *)(HAB_RVT_BASE + 0x20)) #define HAB_RVT_REPORT_STATUS (*(uint32_t *)(HAB_RVT_BASE + 0x24)) +#define HAB_RVT_FAILSAFE (*(uint32_t *)(HAB_RVT_BASE + 0x28)) #define HAB_RVT_REPORT_EVENT_NEW (*(uint32_t *)0x000000B8) #define HAB_RVT_REPORT_STATUS_NEW (*(uint32_t *)0x000000BC) -- cgit From 317956e82cbbd7819d4eb60aeaadafa9f7626339 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:18 +0000 Subject: arm: imx: hab: Implement hab_rvt_failsafe This patch implements the basic callback hooks for hab_rvt_check_failsafe for BootROM code using the older BootROM address layout - in my test case the i.MX7. Code based on new BootROM callbacks will just do nothing and there's definitely a TODO to implement that extra functionality on the alternative BootROM API. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index d1c5f69681..1236717b3e 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -70,6 +70,21 @@ ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ ) +static inline void hab_rvt_failsafe_new(void) +{ +} + +#define hab_rvt_failsafe_p \ +( \ + (is_mx6dqp()) ? \ + ((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) : \ + (is_mx6dq() && (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) : \ + (is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_failsafe_t *)hab_rvt_failsafe_new) : \ + ((hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE) \ +) + static inline enum hab_status hab_rvt_check_target_new(enum hab_target target, const void *start, size_t bytes) -- cgit From 9587b0d61133c025d48ebf480aa021fc2fdd53a7 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 12 Jan 2018 12:40:19 +0000 Subject: arm: imx: hab: Add hab_failsafe console command hab_failsafe when called puts the part into BootROM recovery mode. This will allow u-boot scripts to script the dropping down into recovery mode. => hab_failsafe Shows the i.MX7 appear as "hiddev0,hidraw5: USB HID v1.10 Device [Freescale SemiConductor Inc SP Blank ULT1] " in a Linux dmesg thus allowing download of a new image via the BootROM USB download protocol routine. Signed-off-by: Bryan O'Donoghue Cc: Stefano Babic Cc: Fabio Estevam Cc: Peng Fan Cc: Albert Aribaud Cc: Sven Ebenfeld Cc: George McCollister Cc: Breno Matheus Lima Tested-by: Breno Lima Reviewed-by: Fabio Estevam --- arch/arm/mach-imx/hab.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 1236717b3e..5f197775c1 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -414,6 +414,22 @@ static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, return rcode; } +static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + hab_rvt_failsafe_t *hab_rvt_failsafe; + + if (argc != 1) { + cmd_usage(cmdtp); + return 1; + } + + hab_rvt_failsafe = hab_rvt_failsafe_p; + hab_rvt_failsafe(); + + return 0; +} + U_BOOT_CMD( hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, "display HAB status", @@ -429,6 +445,11 @@ U_BOOT_CMD( "ivt_offset - hex offset of IVT in the image" ); +U_BOOT_CMD( + hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe, + "run BootROM failsafe routine", + "" + ); #endif /* !defined(CONFIG_SPL_BUILD) */ -- cgit