diff options
Diffstat (limited to 'arch')
33 files changed, 654 insertions, 363 deletions
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 3ccde26f1b..96f81a32d6 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += freescale-mx53-qsb/ obj-$(CONFIG_MACH_FREESCALE_MX53_SMD) += freescale-mx53-smd/ obj-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += freescale-mx53-vmx53/ obj-$(CONFIG_MACH_FREESCALE_MX7_SABRESD) += freescale-mx7-sabresd/ +obj-$(CONFIG_MACH_MEERKAT96) += meerkat96/ obj-$(CONFIG_MACH_GE863) += telit-evk-pro3/ obj-$(CONFIG_MACH_GK802) += gk802/ obj-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += globalscale-guruplug/ diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c index 0a30f05aa2..055e5f4c99 100644 --- a/arch/arm/boards/ls1046ardb/lowlevel.c +++ b/arch/arm/boards/ls1046ardb/lowlevel.c @@ -5,7 +5,7 @@ #include <ddr_spd.h> #include <image-metadata.h> #include <platform_data/mmc-esdhc-imx.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> #include <soc/fsl/fsl_ddr_sdram.h> #include <soc/fsl/immap_lsch2.h> #include <asm/barebox-arm-head.h> @@ -187,7 +187,7 @@ static struct fsl_ddr_info ls1046a_info = { static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize) { unsigned long membase = LS1046A_DDR_SDRAM_BASE; - struct fsl_i2c *i2c; + struct pbl_i2c *i2c; int ret; if (get_pc() >= membase) { @@ -205,7 +205,7 @@ static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize) IMD_USED_OF(fsl_ls1046a_rdb); i2c = ls1046_i2c_init(IOMEM(LSCH2_I2C1_BASE_ADDR)); - ret = spd_read_eeprom(i2c, i2c_fsl_xfer, 0x51, &spd_eeprom); + ret = spd_read_eeprom(i2c, 0x51, &spd_eeprom); if (ret) { pr_err("Cannot read SPD EEPROM: %d\n", ret); goto err; diff --git a/arch/arm/boards/meerkat96/Makefile b/arch/arm/boards/meerkat96/Makefile new file mode 100644 index 0000000000..5678718188 --- /dev/null +++ b/arch/arm/boards/meerkat96/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +lwl-y += lowlevel.o +obj-y += board.o diff --git a/arch/arm/boards/meerkat96/board.c b/arch/arm/boards/meerkat96/board.c new file mode 100644 index 0000000000..49e9c06f78 --- /dev/null +++ b/arch/arm/boards/meerkat96/board.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <of.h> +#include <deep-probe.h> + +static const struct of_device_id meerkat96_match[] = { + { .compatible = "novtech,imx7d-meerkat96" }, + { /* Sentinel */ }, +}; +BAREBOX_DEEP_PROBE_ENABLE(meerkat96_match); diff --git a/arch/arm/boards/meerkat96/flash-header-mx7-meerkat96.imxcfg b/arch/arm/boards/meerkat96/flash-header-mx7-meerkat96.imxcfg new file mode 100644 index 0000000000..a49b816178 --- /dev/null +++ b/arch/arm/boards/meerkat96/flash-header-mx7-meerkat96.imxcfg @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + */ + +soc imx7 +loadaddr 0x80000000 +ivtofs 0x400 + +/* + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ + +/* Enable OCRAM EPDC */ +wm 32 0x30340004 0x4F400005 + +/* ============================================================================= + * DDR Controller Registers + * ============================================================================= + * Memory type: DDR3 + * Manufacturer: ISSI + * Device Part Number: IS43TR16256AL-125KBL + * Clock Freq.: 533MHz + * Density per CS in Gb: 4 + * Chip Selects used: 1 + * Number of Banks: 8 + * Row address: 15 + * Column address: 10 + * Data bus width: 16 + * ROW-BANK interleave: ENABLED + * ============================================================================= + */ + +wm 32 0x30391000 0x00000002 // deassert presetn +wm 32 0x307A0000 0x01041001 // DDRC_MSTR +wm 32 0x307A0064 0x00400046 // DDRC_RFSHTMG +wm 32 0x307a0490 0x00000001 // DDRC_PCTRL_0 +wm 32 0x307A00D4 0x00690000 // DDRC_INIT1 +wm 32 0x307A00D0 0x00020083 // DDRC_INIT0 +wm 32 0x307A00DC 0x09300004 // DDRC_INIT3 +wm 32 0x307A00E0 0x04080000 // DDRC_INIT4 +wm 32 0x307A00E4 0x00100004 // DDRC_INIT5 +wm 32 0x307A00F4 0x0000033F // DDRC_RANKCTL +wm 32 0x307A0100 0x090B1109 // DDRC_DRAMTMG0 +wm 32 0x307A0104 0x0007020D // DDRC_DRAMTMG1 +wm 32 0x307A0108 0x03040407 // DDRC_DRAMTMG2 +wm 32 0x307A010C 0x00002006 // DDRC_DRAMTMG3 +wm 32 0x307A0110 0x04020205 // DDRC_DRAMTMG4 +wm 32 0x307A0114 0x03030202 // DDRC_DRAMTMG5 +wm 32 0x307A0120 0x00000803 // DDRC_DRAMTMG8 +wm 32 0x307A0180 0x00800020 // DDRC_ZQCTL0 +wm 32 0x307A0190 0x02098204 // DDRC_DFITMG0 +wm 32 0x307A0194 0x00030303 // DDRC_DFITMG1 +wm 32 0x307A01A0 0x80400003 // DDRC_DFIUPD0 +wm 32 0x307A01A4 0x00100020 // DDRC_DFIUPD1 +wm 32 0x307A01A8 0x80100004 // DDRC_DFIUPD2 +wm 32 0x307A0200 0x00000015 // DDRC_ADDRMAP0 +wm 32 0x307A0204 0x00070707 // DDRC_ADDRMAP1 +wm 32 0x307A0210 0x00000F0F // DDRC_ADDRMAP4 +wm 32 0x307A0214 0x06060606 // DDRC_ADDRMAP5 +wm 32 0x307A0218 0x0F060606 // DDRC_ADDRMAP6 +wm 32 0x307A0240 0x06000604 // DDRC_ODTCFG +wm 32 0x307A0244 0x00000001 // DDRC_ODTMAP + + +/* ============================================================================= + * PHY Control Register + * ============================================================================= + */ + +wm 32 0x30391000 0x00000000 // deassert presetn +wm 32 0x30790000 0x17420F40 // DDR_PHY_PHY_CON0 +wm 32 0x30790004 0x10210100 // DDR_PHY_PHY_CON1 +wm 32 0x30790010 0x00060807 // DDR_PHY_PHY_CON4 +wm 32 0x307900B0 0x1010007E // DDR_PHY_MDLL_CON0 +wm 32 0x3079009C 0x00000D6E // DDR_PHY_DRVDS_CON0 +wm 32 0x30790030 0x08080808 // DDR_PHY_OFFSET_WR_CON0 +wm 32 0x30790020 0x08080808 // DDR_PHY_OFFSET_RD_CON0 +wm 32 0x30790050 0x01000010 // DDR_PHY_OFFSETD_CON0 +wm 32 0x30790050 0x00000010 // DDR_PHY_OFFSETD_CON0 +wm 32 0x30790018 0x0000000F // DDR_PHY_LP_CON0 +wm 32 0x307900C0 0x0E407304 // DDR_PHY_ZQ_CON0 - Start Manual ZQ +wm 32 0x307900C0 0x0E447304 +wm 32 0x307900C0 0x0E447306 +wm 32 0x307900C0 0x0E447304 // <= NOTE: Depending on JTAG device used, may need ~ 7 us pause at this point. +wm 32 0x307900C0 0x0E407304 // DDR_PHY_ZQ_CON0 - End Manual ZQ + + +/* ============================================================================= + * Final Initialization start sequence + * ============================================================================= + */ + +wm 32 0x30384130 0x00000000 // Disable Clock +wm 32 0x30340020 0x00000178 // IOMUX_GRP_GRP8 - Start input to PHY +wm 32 0x30384130 0x00000002 // Enable Clock +/* <= NOTE: Depending on JTAG device used, may need ~ 250 us pause at this point. */ diff --git a/arch/arm/boards/meerkat96/lowlevel.c b/arch/arm/boards/meerkat96/lowlevel.c new file mode 100644 index 0000000000..1c9baeacfb --- /dev/null +++ b/arch/arm/boards/meerkat96/lowlevel.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <debug_ll.h> +#include <io.h> +#include <linux/sizes.h> +#include <mach/debug_ll.h> +#include <mach/iomux-mx7.h> +#include <mach/imx7-ccm-regs.h> +#include <mach/generic.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <asm/cache.h> +extern char __dtb_z_imx7d_meerkat96_start[]; + +static void setup_uart(void) +{ + imx7_early_setup_uart_clock(); + imx7_setup_pad(MX7D_PAD_SD1_WP__UART6_DCE_TX); + imx7_uart_setup_ll(); + putc_ll('>'); +} + +ENTRY_FUNCTION_WITHSTACK(start_imx7d_meerkat96, 0, r0, r1, r2) +{ + void *fdt; + + imx7_cpu_lowlevel_init(); + + setup_uart(); + + fdt = __dtb_z_imx7d_meerkat96_start + get_runtime_offset(); + + barebox_arm_entry(0x80000000, SZ_512M, fdt); +} diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c index 268dfb611a..d22c8b8a74 100644 --- a/arch/arm/boards/mnt-reform/lowlevel.c +++ b/arch/arm/boards/mnt-reform/lowlevel.c @@ -7,7 +7,8 @@ #include <common.h> #include <debug_ll.h> #include <firmware.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> +#include <pbl/pmic.h> #include <mach/atf.h> #include <mach/esdctl.h> #include <mach/generic.h> @@ -18,7 +19,7 @@ #include <mach/xload.h> #include <soc/imx8m/ddr.h> -extern char __dtb_imx8mq_mnt_reform2_start[]; +extern char __dtb_z_imx8mq_mnt_reform2_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(MX8MQ_PAD_CTL_DSE_65R) @@ -36,7 +37,7 @@ static void mnt_reform_setup_uart(void) putc_ll('>'); } -static void i2c_mux_set(void *i2c, u8 channel) +static void i2c_mux_set(struct pbl_i2c *i2c, u8 channel) { int ret; u8 buf[1]; @@ -50,29 +51,14 @@ static void i2c_mux_set(void *i2c, u8 channel) buf[0] = 1 << channel; - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs)); + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs)); if (ret != 1) pr_err("failed to set i2c mux\n"); } -static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs) +static void i2c_regulator_set_voltage(struct pbl_i2c *i2c, u8 reg, u8 voffs) { - int ret; - u8 buf[2]; - struct i2c_msg msgs[] = { - { - .addr = 0x60, - .buf = buf, - .len = 2, - }, - }; - - buf[0] = reg; - buf[1] = 0x80 + voffs; - - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs)); - if (ret != 1) - pr_err("failed to set voltage\n"); + pmic_reg_write(i2c, 0x60, reg, 0x80 + voffs); } #define I2C_PAD_CTRL MUX_PAD_CTRL(MX8MQ_PAD_CTL_DSE_45R | \ @@ -81,7 +67,7 @@ static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs) static void mnt_reform_init_power(void) { - void *i2c; + struct pbl_i2c *i2c; imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL); imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL); @@ -139,7 +125,7 @@ static __noreturn noinline void mnt_reform_start(void) mnt_reform_init_power(); - imx8mq_ddr_init(&mnt_reform_dram_timing); + imx8mq_ddr_init(&mnt_reform_dram_timing, DRAM_TYPE_LPDDR4); imx8mq_get_boot_source(&src, &instance); switch (src) { @@ -173,7 +159,7 @@ static __noreturn noinline void mnt_reform_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mq_barebox_entry(__dtb_imx8mq_mnt_reform2_start); + imx8mq_barebox_entry(__dtb_z_imx8mq_mnt_reform2_start); } ENTRY_FUNCTION(start_mnt_reform, r0, r1, r2) diff --git a/arch/arm/boards/mnt-reform/lpddr4-timing.c b/arch/arm/boards/mnt-reform/lpddr4-timing.c index 0e962890fd..0b5853000d 100644 --- a/arch/arm/boards/mnt-reform/lpddr4-timing.c +++ b/arch/arm/boards/mnt-reform/lpddr4-timing.c @@ -1000,7 +1000,6 @@ static struct dram_fsp_msg mnt_reform_lpddr4_dram_fsp_msg[] = { /* ddr timing config params */ struct dram_timing_info mnt_reform_dram_timing = { - .dram_type = DRAM_TYPE_LPDDR4, .ddrc_cfg = mnt_reform_lpddr4_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(mnt_reform_lpddr4_ddrc_cfg), .ddrphy_cfg = mnt_reform_lpddr4_ddrphy_cfg, diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c index c2f6206cfd..6132df53ec 100644 --- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c @@ -3,27 +3,24 @@ #include <io.h> #include <common.h> #include <debug_ll.h> -#include <firmware.h> #include <asm/mmu.h> #include <asm/cache.h> -#include <asm/sections.h> #include <asm/barebox-arm.h> #include <asm/barebox-arm-head.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> +#include <pbl/pmic.h> #include <linux/sizes.h> -#include <mach/atf.h> -#include <mach/xload.h> #include <mach/esdctl.h> #include <mach/generic.h> #include <mach/imx8mm-regs.h> #include <mach/iomux-mx8mm.h> #include <mach/imx8m-ccm-regs.h> #include <mfd/bd71837.h> +#include <mach/xload.h> #include <soc/imx8m/ddr.h> -#include <soc/fsl/fsl_udc.h> #include <image-metadata.h> -extern char __dtb_imx8mm_evk_start[]; +extern char __dtb_z_imx8mm_evk_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM) @@ -41,30 +38,22 @@ static void setup_uart(void) putc_ll('>'); } -static void pmic_reg_write(void *i2c, int reg, uint8_t val) -{ - int ret; - u8 buf[32]; - struct i2c_msg msgs[] = { - { - .addr = 0x4b, - .buf = buf, - }, - }; - - buf[0] = reg; - buf[1] = val; - - msgs[0].len = 2; - - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs)); - if (ret != 1) - pr_err("Failed to write to pmic\n"); -} +static struct pmic_config bd71837_cfg[] = { + /* decrease RESET key long push time from the default 10s to 10ms */ + { BD718XX_PWRONCONFIG1, 0x0 }, + /* unlock the PMIC regs */ + { BD718XX_REGLOCK, 0x1 }, + /* increase VDD_SOC to typical value 0.85v before first DRAM access */ + { BD718XX_BUCK1_VOLT_RUN, 0x0f }, + /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ + { BD718XX_1ST_NODVS_BUCK_VOLT, 0x83 }, + /* lock the PMIC regs */ + { BD718XX_REGLOCK, 0x11 }, +}; -static int power_init_board(void) +static void power_init_board(void) { - void *i2c; + struct pbl_i2c *i2c; imx8mm_setup_pad(IMX8MM_PAD_I2C1_SCL_I2C1_SCL); imx8mm_setup_pad(IMX8MM_PAD_I2C1_SDA_I2C1_SDA); @@ -74,33 +63,13 @@ static int power_init_board(void) i2c = imx8m_i2c_early_init(IOMEM(MX8MQ_I2C1_BASE_ADDR)); - /* decrease RESET key long push time from the default 10s to 10ms */ - pmic_reg_write(i2c, BD718XX_PWRONCONFIG1, 0x0); - - /* unlock the PMIC regs */ - pmic_reg_write(i2c, BD718XX_REGLOCK, 0x1); - - /* increase VDD_SOC to typical value 0.85v before first DRAM access */ - pmic_reg_write(i2c, BD718XX_BUCK1_VOLT_RUN, 0x0f); - - /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ - pmic_reg_write(i2c, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83); - - /* lock the PMIC regs */ - pmic_reg_write(i2c, BD718XX_REGLOCK, 0x11); - - return 0; + pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg)); } extern struct dram_timing_info imx8mm_evk_dram_timing; static void start_atf(void) { - size_t bl31_size; - const u8 *bl31; - enum bootsource src; - int instance; - /* * If we are in EL3 we are running for the first time and need to * initialize the DRAM and run TF-A (BL31). The TF-A will then jump @@ -110,37 +79,9 @@ static void start_atf(void) return; power_init_board(); - imx8mm_ddr_init(&imx8mm_evk_dram_timing); - - imx8mm_get_boot_source(&src, &instance); - switch (src) { - case BOOTSOURCE_MMC: - imx8m_esdhc_load_image(instance, false); - break; - case BOOTSOURCE_SERIAL: - imx8mm_barebox_load_usb((void *)MX8M_ATF_BL33_BASE_ADDR); - break; - default: - printf("Unhandled bootsource BOOTSOURCE_%d\n", src); - hang(); - } - - /* - * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR - * in EL2. Copy the image there, but replace the PBL part of - * that image with ourselves. On a high assurance boot only the - * currently running code is validated and contains the checksum - * for the piggy data, so we need to ensure that we are running - * the same code in DRAM. - */ - memcpy((void *)MX8M_ATF_BL33_BASE_ADDR, - __image_start, barebox_pbl_size); - - get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size); - - imx8mm_atf_load_bl31(bl31, bl31_size); + imx8mm_ddr_init(&imx8mm_evk_dram_timing, DRAM_TYPE_LPDDR4); - /* not reached */ + imx8mm_load_and_start_image_via_tfa(); } /* @@ -168,7 +109,7 @@ static __noreturn noinline void nxp_imx8mm_evk_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mm_barebox_entry(__dtb_imx8mm_evk_start); + imx8mm_barebox_entry(__dtb_z_imx8mm_evk_start); } ENTRY_FUNCTION(start_nxp_imx8mm_evk, r0, r1, r2) diff --git a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c index 68efbbdf91..e7c01f9cc9 100644 --- a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c +++ b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c @@ -1965,7 +1965,6 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { /* lpddr4 timing config params on EVK board */ struct dram_timing_info imx8mm_evk_dram_timing = { - .dram_type = DRAM_TYPE_LPDDR4, .ddrc_cfg = lpddr4_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), .ddrphy_cfg = lpddr4_ddrphy_cfg, diff --git a/arch/arm/boards/nxp-imx8mn-evk/board.c b/arch/arm/boards/nxp-imx8mn-evk/board.c index 3c478d5f70..3606dabe9d 100644 --- a/arch/arm/boards/nxp-imx8mn-evk/board.c +++ b/arch/arm/boards/nxp-imx8mn-evk/board.c @@ -5,6 +5,7 @@ #include <bootsource.h> #include <common.h> +#include <deep-probe.h> #include <init.h> #include <linux/phy.h> #include <linux/sizes.h> @@ -30,14 +31,11 @@ static int ar8031_phy_fixup(struct phy_device *phydev) return 0; } -static int nxp_imx8mn_evk_init(void) +static int imx8mn_evk_probe(struct device_d *dev) { int emmc_bbu_flag = 0; int sd_bbu_flag = 0; - if (!of_machine_is_compatible("fsl,imx8mn-evk")) - return 0; - if (bootsource_get() == BOOTSOURCE_MMC) { if (bootsource_get_instance() == 2) { of_device_enable_path("/chosen/environment-emmc"); @@ -59,4 +57,17 @@ static int nxp_imx8mn_evk_init(void) return 0; } -coredevice_initcall(nxp_imx8mn_evk_init); + +static const struct of_device_id imx8mn_evk_of_match[] = { + { .compatible = "fsl,imx8mn-evk" }, + { .compatible = "fsl,imx8mn-ddr4-evk" }, + { /* sentinel */ }, +}; +BAREBOX_DEEP_PROBE_ENABLE(imx8mn_evk_of_match); + +static struct driver_d imx8mn_evkboard_driver = { + .name = "board-imx8mn-evk", + .probe = imx8mn_evk_probe, + .of_compatible = DRV_OF_COMPAT(imx8mn_evk_of_match), +}; +coredevice_platform_driver(imx8mn_evkboard_driver); diff --git a/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c b/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c index 7ce371384e..131a63156e 100644 --- a/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c +++ b/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c @@ -1040,7 +1040,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { /* ddr timing config params */ struct dram_timing_info imx8mn_evk_ddr4_timing = { - .dram_type = DRAM_TYPE_DDR4, .ddrc_cfg = ddr_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), .ddrphy_cfg = ddr_ddrphy_cfg, diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c index de53213ebc..7da9c33565 100644 --- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c @@ -9,7 +9,8 @@ #include <asm/sections.h> #include <asm/barebox-arm.h> #include <asm/barebox-arm-head.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> +#include <pbl/pmic.h> #include <linux/sizes.h> #include <mach/atf.h> #include <mach/xload.h> @@ -22,8 +23,6 @@ #include <mfd/bd71837.h> #include <soc/imx8m/ddr.h> -extern char __dtb_z_imx8mn_evk_start[]; - static void setup_uart(void) { void __iomem *uart = IOMEM(MX8M_UART2_BASE_ADDR); @@ -38,108 +37,50 @@ static void setup_uart(void) putc_ll('>'); } -static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val) -{ - int ret; - u8 buf[32]; - struct i2c_msg msgs[] = { - { - .addr = addr, - .buf = buf, - }, - }; - - buf[0] = reg; - buf[1] = val; - - msgs[0].len = 2; - - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs)); - if (ret != 1) - pr_err("Failed to write to pmic@%x: %d\n", addr, ret); -} - -static int power_init_board_pca9450(void *i2c, int addr) -{ - u8 buf[1]; - struct i2c_msg msgs[] = { - { - .addr = addr, - .buf = buf, - .flags = I2C_M_RD, - .len = 1, - }, - }; - - if (i2c_fsl_xfer(i2c, msgs, 1) != 1) - return -ENODEV; - +static struct pmic_config pca9450_cfg[] = { /* BUCKxOUT_DVS0/1 control BUCK123 output */ - pmic_reg_write(i2c, addr, PCA9450_BUCK123_DVS, 0x29); - + { PCA9450_BUCK123_DVS, 0x29 }, /* * increase VDD_SOC to typical value 0.95V before first * DRAM access, set DVS1 to 0.85v for suspend. * Enable DVS control through PMIC_STBY_REQ and * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) */ - pmic_reg_write(i2c, addr, PCA9450_BUCK1OUT_DVS0, 0x1C); - + { PCA9450_BUCK1OUT_DVS0, 0x1C }, /* Set DVS1 to 0.85v for suspend */ /* Enable DVS control through PMIC_STBY_REQ and set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) */ - pmic_reg_write(i2c, addr, PCA9450_BUCK1OUT_DVS1, 0x14); - pmic_reg_write(i2c, addr, PCA9450_BUCK1CTRL, 0x59); - + { PCA9450_BUCK1OUT_DVS1, 0x14 }, + { PCA9450_BUCK1CTRL, 0x59 }, /* set VDD_SNVS_0V8 from default 0.85V */ - pmic_reg_write(i2c, addr, PCA9450_LDO2CTRL, 0xC0); - + { PCA9450_LDO2CTRL, 0xC0 }, /* enable LDO4 to 1.2v */ - pmic_reg_write(i2c, addr, PCA9450_LDO4CTRL, 0x44); - + { PCA9450_LDO4CTRL, 0x44 }, /* set WDOG_B_CFG to cold reset */ - pmic_reg_write(i2c, addr, PCA9450_RESET_CTRL, 0xA1); - - return 0; -} + { PCA9450_RESET_CTRL, 0xA1 }, +}; -static int power_init_board_bd71837(void *i2c, int addr) -{ +static struct pmic_config bd71837_cfg[] = { /* decrease RESET key long push time from the default 10s to 10ms */ - pmic_reg_write(i2c, addr, BD718XX_PWRONCONFIG1, 0x0); - + { BD718XX_PWRONCONFIG1, 0x0 }, /* unlock the PMIC regs */ - pmic_reg_write(i2c, addr, BD718XX_REGLOCK, 0x1); - + { BD718XX_REGLOCK, 0x1 }, /* Set VDD_ARM to typical value 0.85v for 1.2Ghz */ - pmic_reg_write(i2c, addr, BD718XX_BUCK2_VOLT_RUN, 0xf); - + { BD718XX_BUCK2_VOLT_RUN, 0xf }, /* Set VDD_SOC/VDD_DRAM to typical value 0.85v for nominal mode */ - pmic_reg_write(i2c, addr, BD718XX_BUCK1_VOLT_RUN, 0xf); - + { BD718XX_BUCK1_VOLT_RUN, 0xf }, /* Set VDD_SOC 0.85v for suspend */ - pmic_reg_write(i2c, addr, BD718XX_BUCK1_VOLT_SUSP, 0xf); - - /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 - * */ - pmic_reg_write(i2c, addr, BD718XX_4TH_NODVS_BUCK_CTRL, 0x28); - + { BD718XX_BUCK1_VOLT_SUSP, 0xf }, + /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */ + { BD718XX_4TH_NODVS_BUCK_CTRL, 0x28 }, /* lock the PMIC regs */ - pmic_reg_write(i2c, addr, BD718XX_REGLOCK, 0x11); - - return 0; -} + { BD718XX_REGLOCK, 0x11 }, +}; extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing; static void start_atf(void) { - struct dram_timing_info *dram_timing = &imx8mn_evk_lpddr4_timing; - size_t bl31_size; - const u8 *bl31; - enum bootsource src; - void *i2c; - int instance; - int ret; + struct pbl_i2c *i2c; /* * If we are in EL3 we are running for the first time and need to @@ -157,40 +98,15 @@ static void start_atf(void) i2c = imx8m_i2c_early_init(IOMEM(MX8MN_I2C1_BASE_ADDR)); - ret = power_init_board_pca9450(i2c, 0x25); - if (ret) { - power_init_board_bd71837(i2c, 0x4b); - dram_timing = &imx8mn_evk_ddr4_timing; - } - - imx8mn_ddr_init(dram_timing); - - imx8mn_get_boot_source(&src, &instance); - switch (src) { - case BOOTSOURCE_MMC: - imx8mn_esdhc_load_image(instance, false); - break; - default: - printf("Unhandled bootsource BOOTSOURCE_%d\n", src); - hang(); + if (i2c_dev_probe(i2c, 0x25, true) == 0) { + pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg)); + imx8mn_ddr_init(&imx8mn_evk_lpddr4_timing, DRAM_TYPE_LPDDR4); + } else { + pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg)); + imx8mn_ddr_init(&imx8mn_evk_ddr4_timing, DRAM_TYPE_DDR4); } - /* - * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR - * in EL2. Copy the image there, but replace the PBL part of - * that image with ourselves. On a high assurance boot only the - * currently running code is validated and contains the checksum - * for the piggy data, so we need to ensure that we are running - * the same code in DRAM. - */ - memcpy((void *)MX8M_ATF_BL33_BASE_ADDR, - __image_start, barebox_pbl_size); - - get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size); - - imx8mn_atf_load_bl31(bl31, bl31_size); - - /* not reached */ + imx8mn_load_and_start_image_via_tfa(); } /* @@ -211,14 +127,23 @@ static void start_atf(void) */ static __noreturn noinline void nxp_imx8mn_evk_start(void) { + extern char __dtb_z_imx8mn_evk_start[], __dtb_z_imx8mn_ddr4_evk_start[]; + void *fdt; + setup_uart(); start_atf(); + /* Check if we configured DDR4 in EL3 */ + if (readl(MX8M_DDRC_CTL_BASE_ADDR) & BIT(4)) + fdt = __dtb_z_imx8mn_ddr4_evk_start; + else + fdt = __dtb_z_imx8mn_evk_start; + /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mn_barebox_entry(__dtb_z_imx8mn_evk_start); + imx8mn_barebox_entry(fdt); } ENTRY_FUNCTION(start_nxp_imx8mn_evk, r0, r1, r2) diff --git a/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c index c53bcc705d..940b21cedb 100644 --- a/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c +++ b/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c @@ -1576,7 +1576,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { /* ddr timing config params */ struct dram_timing_info imx8mn_evk_lpddr4_timing = { - .dram_type = DRAM_TYPE_LPDDR4, .ddrc_cfg = ddr_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), .ddrphy_cfg = ddr_ddrphy_cfg, diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c index c7916e4962..4f24dd4cd4 100644 --- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c @@ -10,7 +10,8 @@ #include <asm/sections.h> #include <asm/barebox-arm.h> #include <asm/barebox-arm-head.h> -#include <i2c/i2c-early.h> +#include <pbl/i2c.h> +#include <pbl/pmic.h> #include <linux/sizes.h> #include <mach/atf.h> #include <mach/xload.h> @@ -23,7 +24,7 @@ #include <soc/imx8m/ddr.h> #include <soc/fsl/fsl_udc.h> -extern char __dtb_imx8mp_evk_start[]; +extern char __dtb_z_imx8mp_evk_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(MX8MP_PAD_CTL_DSE6 | \ MX8MP_PAD_CTL_FSEL) @@ -48,30 +49,25 @@ static void setup_uart(void) putc_ll('>'); } -static void pmic_reg_write(void *i2c, int reg, uint8_t val) -{ - int ret; - u8 buf[32]; - struct i2c_msg msgs[] = { - { - .addr = 0x25, - .buf = buf, - }, - }; - - buf[0] = reg; - buf[1] = val; - - msgs[0].len = 2; - - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs)); - if (ret != 1) - pr_err("Failed to write to pmic\n"); -} +static struct pmic_config pca9450_cfg[] = { + /* BUCKxOUT_DVS0/1 control BUCK123 output */ + { PCA9450_BUCK123_DVS, 0x29 }, + /* + * increase VDD_SOC to typical value 0.95V before first + * DRAM access, set DVS1 to 0.85v for suspend. + * Enable DVS control through PMIC_STBY_REQ and + * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) + */ + { PCA9450_BUCK1OUT_DVS0, 0x1C }, + { PCA9450_BUCK1OUT_DVS1, 0x14 }, + { PCA9450_BUCK1CTRL, 0x59 }, + /* set WDOG_B_CFG to cold reset */ + { PCA9450_RESET_CTRL, 0xA1 }, +}; -static int power_init_board(void) +static void power_init_board(void) { - void *i2c; + struct pbl_i2c *i2c; imx8mp_setup_pad(MX8MP_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL); imx8mp_setup_pad(MX8MP_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL); @@ -81,34 +77,13 @@ static int power_init_board(void) i2c = imx8m_i2c_early_init(IOMEM(MX8MP_I2C1_BASE_ADDR)); - /* BUCKxOUT_DVS0/1 control BUCK123 output */ - pmic_reg_write(i2c, PCA9450_BUCK123_DVS, 0x29); - - /* - * increase VDD_SOC to typical value 0.95V before first - * DRAM access, set DVS1 to 0.85v for suspend. - * Enable DVS control through PMIC_STBY_REQ and - * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) - */ - pmic_reg_write(i2c, PCA9450_BUCK1OUT_DVS0, 0x1C); - pmic_reg_write(i2c, PCA9450_BUCK1OUT_DVS1, 0x14); - pmic_reg_write(i2c, PCA9450_BUCK1CTRL, 0x59); - - /* set WDOG_B_CFG to cold reset */ - pmic_reg_write(i2c, PCA9450_RESET_CTRL, 0xA1); - - return 0; + pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg)); } extern struct dram_timing_info imx8mp_evk_dram_timing; static void start_atf(void) { - size_t bl31_size; - const u8 *bl31; - enum bootsource src; - int instance; - /* * If we are in EL3 we are running for the first time and need to * initialize the DRAM and run TF-A (BL31). The TF-A will then jump @@ -119,35 +94,9 @@ static void start_atf(void) power_init_board(); - imx8mp_ddr_init(&imx8mp_evk_dram_timing); - - imx8mp_get_boot_source(&src, &instance); - switch (src) { - case BOOTSOURCE_MMC: - imx8mp_esdhc_load_image(instance, false); - break; - default: - printf("Unhandled bootsource BOOTSOURCE_%d\n", src); - hang(); - } - - - /* - * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR - * in EL2. Copy the image there, but replace the PBL part of - * that image with ourselves. On a high assurance boot only the - * currently running code is validated and contains the checksum - * for the piggy data, so we need to ensure that we are running - * the same code in DRAM. - */ - memcpy((void *)MX8M_ATF_BL33_BASE_ADDR, - __image_start, barebox_pbl_size); - - get_builtin_firmware(imx8mp_bl31_bin, &bl31, &bl31_size); - - imx8mp_atf_load_bl31(bl31, bl31_size); + imx8mp_ddr_init(&imx8mp_evk_dram_timing, DRAM_TYPE_LPDDR4); - /* not reached */ + imx8mp_load_and_start_image_via_tfa(); } /* @@ -175,7 +124,7 @@ static __noreturn noinline void nxp_imx8mp_evk_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mp_barebox_entry(__dtb_imx8mp_evk_start); + imx8mp_barebox_entry(__dtb_z_imx8mp_evk_start); } ENTRY_FUNCTION(start_nxp_imx8mp_evk, r0, r1, r2) diff --git a/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c index 681e70d060..3028bc084c 100644 --- a/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c +++ b/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c @@ -1834,7 +1834,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { /* ddr timing config params */ struct dram_timing_info imx8mp_evk_dram_timing = { - .dram_type = DRAM_TYPE_LPDDR4, .ddrc_cfg = ddr_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), .ddrphy_cfg = ddr_ddrphy_cfg, diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c index 92cc22e022..0c9f6345ff 100644 --- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c +++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c @@ -21,7 +21,7 @@ #include "ddr.h" -extern char __dtb_imx8mq_evk_start[]; +extern char __dtb_z_imx8mq_evk_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM) @@ -97,7 +97,7 @@ static __noreturn noinline void nxp_imx8mq_evk_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mq_barebox_entry(__dtb_imx8mq_evk_start); + imx8mq_barebox_entry(__dtb_z_imx8mq_evk_start); } ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2) diff --git a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c index 05226866f8..d35f9b0d39 100644 --- a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c +++ b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c @@ -23,7 +23,7 @@ #include "ddr.h" -extern char __dtb_imx8mq_phytec_phycore_som_start[]; +extern char __dtb_z_imx8mq_phytec_phycore_som_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM) @@ -90,7 +90,7 @@ static __noreturn noinline void phytec_phycore_imx8mq_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mq_barebox_entry(__dtb_imx8mq_phytec_phycore_som_start); + imx8mq_barebox_entry(__dtb_z_imx8mq_phytec_phycore_som_start); } /* diff --git a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c index 24d98fe6c9..bfae39ea52 100644 --- a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c +++ b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c @@ -15,7 +15,7 @@ #include <soc/fsl/fsl_udc.h> #include <soc/imx8m/ddr.h> -extern char __dtb_imx8mm_prt8mm_start[]; +extern char __dtb_z_imx8mm_prt8mm_start[]; #define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM) @@ -37,11 +37,6 @@ extern struct dram_timing_info prt8mm_dram_timing; static void start_atf(void) { - size_t bl31_size; - const u8 *bl31; - enum bootsource src; - int instance; - /* * If we are in EL3 we are running for the first time and need to * initialize the DRAM and run TF-A (BL31). The TF-A will then jump @@ -52,36 +47,9 @@ static void start_atf(void) imx8mm_early_clock_init(); - imx8mm_ddr_init(&prt8mm_dram_timing); - - imx8mm_get_boot_source(&src, &instance); - switch (src) { - case BOOTSOURCE_MMC: - imx8m_esdhc_load_image(instance, false); - break; - case BOOTSOURCE_SERIAL: - imx8mm_barebox_load_usb((void *)MX8M_ATF_BL33_BASE_ADDR); - break; - default: - printf("Unhandled bootsource BOOTSOURCE_%d\n", src); - hang(); - } - - /* - * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR - * in EL2. Copy the image there, but replace the PBL part of - * that image with ourselves. On a high assurance boot only the - * currently running code is validated and contains the checksum - * for the piggy data, so we need to ensure that we are running - * the same code in DRAM. - */ - memcpy((void *)MX8MM_ATF_BL33_BASE_ADDR, - __image_start, barebox_pbl_size); - - get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size); - imx8mm_atf_load_bl31(bl31, bl31_size); + imx8mm_ddr_init(&prt8mm_dram_timing, DRAM_TYPE_LPDDR4); - /* not reached */ + imx8mm_load_and_start_image_via_tfa(); } /* @@ -109,7 +77,7 @@ static __noreturn noinline void prt_prt8mm_start(void) /* * Standard entry we hit once we initialized both DDR and ATF */ - imx8mm_barebox_entry(__dtb_imx8mm_prt8mm_start); + imx8mm_barebox_entry(__dtb_z_imx8mm_prt8mm_start); } ENTRY_FUNCTION(start_prt_prt8mm, r0, r1, r2) diff --git a/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c b/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c index ea5c0b9154..2c55e7d451 100644 --- a/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c +++ b/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c @@ -1981,7 +1981,6 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { /* lpddr4 timing config params on EVK board */ struct dram_timing_info prt8mm_dram_timing = { - .dram_type = DRAM_TYPE_LPDDR4, .ddrc_cfg = lpddr4_ddrc_cfg, .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), .ddrphy_cfg = lpddr4_ddrphy_cfg, diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index 8e707b9602..df2304eae9 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -13,7 +13,6 @@ CONFIG_MACH_FREESCALE_MX53_VMX53=y CONFIG_MACH_TX53=y CONFIG_MACH_PHYTEC_SOM_IMX6=y CONFIG_MACH_PROTONIC_IMX6=y -CONFIG_MACH_KAMSTRUP_MX7_CONCENTRATOR=y CONFIG_MACH_KONTRON_SAMX6I=y CONFIG_MACH_DFI_FS700_M60=y CONFIG_MACH_GUF_SANTARO=y @@ -38,7 +37,8 @@ CONFIG_MACH_GW_VENTANA=y CONFIG_MACH_CM_FX6=y CONFIG_MACH_ADVANTECH_ROM_742X=y CONFIG_MACH_WARP7=y -CONFIG_MACH_WEBASTO_CCBV2=y +CONFIG_MACH_AC_SXB=y +CONFIG_MACH_MEERKAT96=y CONFIG_MACH_VF610_TWR=y CONFIG_MACH_ZII_RDU1=y CONFIG_MACH_ZII_RDU2=y @@ -46,9 +46,12 @@ CONFIG_MACH_ZII_VF610_DEV=y CONFIG_MACH_ZII_IMX7D_DEV=y CONFIG_MACH_PHYTEC_PHYCORE_IMX7=y CONFIG_MACH_FREESCALE_MX7_SABRESD=y +CONFIG_MACH_KAMSTRUP_MX7_CONCENTRATOR=y CONFIG_MACH_NXP_IMX6ULL_EVK=y CONFIG_MACH_GRINN_LITEBOARD=y CONFIG_MACH_DIGI_CCIMX6ULSBCPRO=y +CONFIG_MACH_WEBASTO_CCBV2=y +CONFIG_MACH_SKOV_IMX6=y CONFIG_IMX_IIM_FUSE_BLOW=y CONFIG_THUMB2_BAREBOX=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y @@ -87,6 +90,7 @@ CONFIG_CMD_MMC_EXTCSD=y CONFIG_CMD_GO=y CONFIG_CMD_RESET=y CONFIG_CMD_UIMAGE=y +CONFIG_CMD_BOOTCHOOSER=y CONFIG_CMD_PARTITION=y CONFIG_CMD_UBIFORMAT=y CONFIG_CMD_EXPORT=y @@ -139,7 +143,6 @@ CONFIG_CMD_OF_OVERLAY=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_CMD_STATE=y -CONFIG_CMD_BOOTCHOOSER=y CONFIG_NET=y CONFIG_NET_NETCONSOLE=y CONFIG_OF_BAREBOX_DRIVERS=y @@ -198,9 +201,9 @@ CONFIG_WATCHDOG=y CONFIG_WATCHDOG_IMX=y CONFIG_PWM=y CONFIG_PWM_IMX=y -CONFIG_IMX_OCOTP_WRITE=y CONFIG_MXS_APBH_DMA=y CONFIG_GPIO_STMPE=y +CONFIG_IMX_OCOTP_WRITE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y CONFIG_GENERIC_PHY=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 980a2487a0..4e935a7632 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -26,6 +26,7 @@ lwl-$(CONFIG_MACH_CCMX53) += imx53-ccxmx53.dtb.o lwl-$(CONFIG_MACH_DIGI_CCIMX6ULSBCPRO) += imx6ul-ccimx6ulsbcpro.dtb.o lwl-$(CONFIG_MACH_FREESCALE_MX53_VMX53) += imx53-voipac-bsb.dtb.o lwl-$(CONFIG_MACH_FREESCALE_MX7_SABRESD) += imx7d-sdb.dtb.o +lwl-$(CONFIG_MACH_MEERKAT96) += imx7d-meerkat96.dtb.o lwl-$(CONFIG_MACH_GK802) += imx6q-gk802.dtb.o lwl-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += kirkwood-guruplug-server-plus-bb.dtb.o lwl-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += armada-370-mirabox-bb.dtb.o @@ -140,7 +141,7 @@ lwl-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += imx6q-wandboard.dtb.o imx6dl-wandboar lwl-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += imx6ul-pico-hobbit.dtb.o lwl-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += imx6ull-14x14-evk.dtb.o lwl-$(CONFIG_MACH_NXP_IMX8MM_EVK) += imx8mm-evk.dtb.o -lwl-$(CONFIG_MACH_NXP_IMX8MN_EVK) += imx8mn-evk.dtb.o +lwl-$(CONFIG_MACH_NXP_IMX8MN_EVK) += imx8mn-evk.dtb.o imx8mn-ddr4-evk.dtb.o lwl-$(CONFIG_MACH_NXP_IMX8MP_EVK) += imx8mp-evk.dtb.o lwl-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += imx8mq-evk.dtb.o lwl-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += tegra20-colibri-iris.dtb.o diff --git a/arch/arm/dts/imx7d-meerkat96.dts b/arch/arm/dts/imx7d-meerkat96.dts new file mode 100644 index 0000000000..f9d18f355b --- /dev/null +++ b/arch/arm/dts/imx7d-meerkat96.dts @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +#include <arm/imx7d-meerkat96.dts> + +/ { + chosen { + environment { + compatible = "barebox,environment"; + device-path = &bareboxenv; + }; + }; +}; + +&usdhc1 { + #address-cells = <1>; + #size-cells = <1>; + + barebox@0 { + label = "barebox"; + reg = <0x0 0x180000>; + }; + + bareboxenv: bareboxenv@180000 { + label = "bareboxenv"; + reg = <0x180000 0x80000>; + }; +}; + +/* FIXME: barebox serial is broken when barebox applies requested reparenting */ +&uart1 { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; +}; + +&uart3 { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; +}; + +&uart6 { + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; +}; diff --git a/arch/arm/dts/imx8mn-ddr4-evk.dts b/arch/arm/dts/imx8mn-ddr4-evk.dts new file mode 100644 index 0000000000..6ebb4d15e4 --- /dev/null +++ b/arch/arm/dts/imx8mn-ddr4-evk.dts @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +/dts-v1/; + +#include <arm64/freescale/imx8mn-ddr4-evk.dts> +#include "imx8mn-evk.dtsi" diff --git a/arch/arm/dts/imx8mn-evk.dts b/arch/arm/dts/imx8mn-evk.dts index 23f80f8686..cbb8b8874c 100644 --- a/arch/arm/dts/imx8mn-evk.dts +++ b/arch/arm/dts/imx8mn-evk.dts @@ -1,12 +1,9 @@ // SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright 2017 NXP - * Copyright (C) 2017 Pengutronix, Lucas Stach <kernel@pengutronix.de> - */ /dts-v1/; #include <arm64/freescale/imx8mn-evk.dts> +#include "imx8mn-evk.dtsi" #include "imx8mn.dtsi" / { @@ -90,4 +87,3 @@ #size-cells = <1>; }; }; - diff --git a/arch/arm/dts/imx8mn-evk.dtsi b/arch/arm/dts/imx8mn-evk.dtsi new file mode 100644 index 0000000000..ceeb5f8b93 --- /dev/null +++ b/arch/arm/dts/imx8mn-evk.dtsi @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017 NXP + * Copyright (C) 2017 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +/ { + chosen { + environment-sd { + compatible = "barebox,environment"; + device-path = &usdhc2, "partname:barebox-environment"; + status = "disabled"; + }; + environment-emmc { + compatible = "barebox,environment"; + device-path = &usdhc3, "partname:barebox-environment"; + status = "disabled"; + }; + }; +}; + +&usdhc2 { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0xe0000>; + }; + + partition@e0000 { + label = "barebox-environment"; + reg = <0xe0000 0x20000>; + }; +}; + +&usdhc3 { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0xe0000>; + }; + + partition@e0000 { + label = "barebox-environment"; + reg = <0xe0000 0x20000>; + }; +}; + +&ocotp { + barebox,provide-mac-address = <&fec1 0x640>; +}; + +&iomuxc { + pinctrl_flexspi0: flexspi0grp { + fsl,pins = < + MX8MN_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c4 + MX8MN_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x84 + MX8MN_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x84 + MX8MN_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x84 + MX8MN_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x84 + MX8MN_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x84 + >; + }; +}; + +&flexspi { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexspi0>; + + system_flash: flash@0 { + reg = <0>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <80000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 9ff549ac83..ca60f85c28 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -183,6 +183,7 @@ config ARCH_IMX8M select HW_HAS_PCI select IMX8M_DRAM select PBL_VERIFY_PIGGY if HABV4 + select ARM_USE_COMPRESSED_DTB config ARCH_IMX8MM select ARCH_IMX8M @@ -485,6 +486,11 @@ config MACH_AC_SXB select MCI_IMX_ESDHC_PBL select ARM_USE_COMPRESSED_DTB +config MACH_MEERKAT96 + bool "96Boards: i.MX7 Meerkat96" + select ARCH_IMX7 + select ARM_USE_COMPRESSED_DTB + config MACH_VF610_TWR bool "Freescale VF610 Tower Board" select ARCH_VF610 @@ -515,7 +521,6 @@ config MACH_ZII_IMX8MQ_DEV select ARM_SMCCC select MCI_IMX_ESDHC_PBL select MACH_ZII_COMMON - select ARM_USE_COMPRESSED_DTB config MACH_ZII_VF610_DEV bool "ZII VF610 Dev Family" @@ -575,7 +580,6 @@ config MACH_NXP_IMX8MN_EVK select MCI_IMX_ESDHC_PBL select IMX8M_DRAM select I2C_IMX_EARLY - select ARM_USE_COMPRESSED_DTB config MACH_NXP_IMX8MP_EVK bool "NXP i.MX8MP EVK Board" @@ -586,7 +590,6 @@ config MACH_NXP_IMX8MP_EVK select MCI_IMX_ESDHC_PBL select IMX8M_DRAM select I2C_IMX_EARLY - select USB_GADGET_DRIVER_ARC_PBL config MACH_NXP_IMX8MQ_EVK bool "NXP i.MX8MQ EVK Board" diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 2cafcd77e0..fa5133a229 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -18,7 +18,7 @@ lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o obj-$(CONFIG_ARCH_IMX7) += imx7.o obj-$(CONFIG_ARCH_VF610) += vf610.o obj-pbl-$(CONFIG_ARCH_IMX8M) += imx8m.o -lwl-$(CONFIG_ARCH_IMX8M) += atf.o +lwl-$(CONFIG_ARCH_IMX8M) += atf.o romapi.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_NAND_IMX) += nand.o lwl-$(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND) += external-nand-boot.o diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c index 9ab9ddd203..a4c6582830 100644 --- a/arch/arm/mach-imx/atf.c +++ b/arch/arm/mach-imx/atf.c @@ -1,7 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <asm/sections.h> #include <common.h> +#include <firmware.h> #include <mach/atf.h> +#include <mach/generic.h> +#include <mach/xload.h> +#include <mach/romapi.h> +#include <soc/fsl/fsl_udc.h> /** * imx8m_atf_load_bl31 - Load ATF BL31 blob and transfer control to it @@ -63,3 +69,141 @@ void imx8mq_atf_load_bl31(const void *fw, size_t fw_size) { imx8m_atf_load_bl31(fw, fw_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR); } + +void imx8mm_load_and_start_image_via_tfa(void) +{ + size_t bl31_size; + const u8 *bl31; + enum bootsource src; + int instance; + void *bl33 = (void *)MX8M_ATF_BL33_BASE_ADDR; + + imx8mm_get_boot_source(&src, &instance); + switch (src) { + case BOOTSOURCE_MMC: + imx8m_esdhc_load_image(instance, false); + break; + case BOOTSOURCE_SERIAL: + /* + * Traditionally imx-usb-loader sends the PBL twice. The first + * PBL is loaded to OCRAM and executed. Then the full barebox + * image including the PBL is sent again and received here. We + * might change that in the future in imx-usb-loader so that the + * PBL is sent only once and we only receive the rest of the + * image here. To prepare that step we check if we get a full + * barebox image or piggydata only. When it's piggydata only move + * it to the place where it would be if it would have been a + * full image. + */ + imx8mm_barebox_load_usb(bl33); + + if (!strcmp("barebox", bl33 + 0x20)) { + /* Found the barebox marker, so this is a PBL + piggydata */ + pr_debug("received PBL + piggydata\n"); + } else { + /* no barebox marker, so this is piggydata only */ + pr_debug("received piggydata\n"); + memmove(bl33 + barebox_pbl_size, bl33, + barebox_image_size - barebox_pbl_size); + } + + break; + default: + printf("Unhandled bootsource BOOTSOURCE_%d\n", src); + hang(); + } + + /* + * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR + * in EL2. Copy the image there, but replace the PBL part of + * that image with ourselves. On a high assurance boot only the + * currently running code is validated and contains the checksum + * for the piggy data, so we need to ensure that we are running + * the same code in DRAM. + */ + memcpy(bl33, __image_start, barebox_pbl_size); + + get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size); + + imx8mm_atf_load_bl31(bl31, bl31_size); + + /* not reached */ +} + +void imx8mp_load_and_start_image_via_tfa(void) +{ + size_t bl31_size; + const u8 *bl31; + enum bootsource src; + int instance; + + imx8mp_get_boot_source(&src, &instance); + switch (src) { + case BOOTSOURCE_MMC: + imx8mp_esdhc_load_image(instance, false); + break; + case BOOTSOURCE_SERIAL: + imx8mp_bootrom_load_image(); + break; + default: + printf("Unhandled bootsource BOOTSOURCE_%d\n", src); + hang(); + } + + + /* + * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR + * in EL2. Copy the image there, but replace the PBL part of + * that image with ourselves. On a high assurance boot only the + * currently running code is validated and contains the checksum + * for the piggy data, so we need to ensure that we are running + * the same code in DRAM. + */ + memcpy((void *)MX8M_ATF_BL33_BASE_ADDR, + __image_start, barebox_pbl_size); + + get_builtin_firmware(imx8mp_bl31_bin, &bl31, &bl31_size); + + imx8mp_atf_load_bl31(bl31, bl31_size); + + /* not reached */ +} + +void imx8mn_load_and_start_image_via_tfa(void) +{ + size_t bl31_size; + const u8 *bl31; + enum bootsource src; + int instance; + + imx8mn_get_boot_source(&src, &instance); + switch (src) { + case BOOTSOURCE_MMC: + imx8mn_esdhc_load_image(instance, false); + break; + case BOOTSOURCE_SERIAL: + imx8mn_bootrom_load_image(); + break; + default: + printf("Unhandled bootsource BOOTSOURCE_%d\n", src); + hang(); + } + + + /* + * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR + * in EL2. Copy the image there, but replace the PBL part of + * that image with ourselves. On a high assurance boot only the + * currently running code is validated and contains the checksum + * for the piggy data, so we need to ensure that we are running + * the same code in DRAM. + */ + memcpy((void *)MX8M_ATF_BL33_BASE_ADDR, + __image_start, barebox_pbl_size); + + get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size); + + imx8mn_atf_load_bl31(bl31, bl31_size); + + /* not reached */ +} diff --git a/arch/arm/mach-imx/include/mach/atf.h b/arch/arm/mach-imx/include/mach/atf.h index 09396f4646..bc400ddbad 100644 --- a/arch/arm/mach-imx/include/mach/atf.h +++ b/arch/arm/mach-imx/include/mach/atf.h @@ -10,7 +10,7 @@ #define MX8MM_ATF_BL31_BASE_ADDR 0x00920000 #define MX8MN_ATF_BL31_BASE_ADDR 0x00960000 -#define MX8MP_ATF_BL31_BASE_ADDR 0x00960000 +#define MX8MP_ATF_BL31_BASE_ADDR 0x00970000 #define MX8MQ_ATF_BL31_BASE_ADDR 0x00910000 #define MX8M_ATF_BL33_BASE_ADDR 0x40200000 #define MX8MM_ATF_BL33_BASE_ADDR MX8M_ATF_BL33_BASE_ADDR diff --git a/arch/arm/mach-imx/include/mach/romapi.h b/arch/arm/mach-imx/include/mach/romapi.h new file mode 100644 index 0000000000..8022fc411e --- /dev/null +++ b/arch/arm/mach-imx/include/mach/romapi.h @@ -0,0 +1,37 @@ +#ifndef __MACH_IMX_ROMAPI_H +#define __MACH_IMX_ROMAPI_H + +struct rom_api { + u16 ver; + u16 tag; + u32 reserved1; + u32 (*download_image)(u8 *dest, u32 offset, u32 size, u32 xor); + u32 (*query_boot_infor)(u32 info_type, u32 *info, u32 xor); +}; + +enum boot_dev_type_e { + BT_DEV_TYPE_SD = 1, + BT_DEV_TYPE_MMC = 2, + BT_DEV_TYPE_NAND = 3, + BT_DEV_TYPE_FLEXSPINOR = 4, + BT_DEV_TYPE_SPI_NOR = 6, + + BT_DEV_TYPE_USB = 0xE, + BT_DEV_TYPE_MEM_DEV = 0xF, + + BT_DEV_TYPE_INVALID = 0xFF +}; + +#define QUERY_ROM_VER 1 +#define QUERY_BT_DEV 2 +#define QUERY_PAGE_SZ 3 +#define QUERY_IVT_OFF 4 +#define QUERY_BT_STAGE 5 +#define QUERY_IMG_OFF 6 + +#define ROM_API_OKAY 0xF0 + +int imx8mp_bootrom_load_image(void); +int imx8mn_bootrom_load_image(void); + +#endif /* __MACH_IMX_ROMAPI_H */ diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h index 03ec23ebbd..3090c9c83b 100644 --- a/arch/arm/mach-imx/include/mach/xload.h +++ b/arch/arm/mach-imx/include/mach/xload.h @@ -13,6 +13,10 @@ int imx8m_esdhc_load_image(int instance, bool start); int imx8mn_esdhc_load_image(int instance, bool start); int imx8mp_esdhc_load_image(int instance, bool start); +void imx8mm_load_and_start_image_via_tfa(void); +void imx8mn_load_and_start_image_via_tfa(void); +void imx8mp_load_and_start_image_via_tfa(void); + int imx_image_size(void); int piggydata_size(void); diff --git a/arch/arm/mach-imx/romapi.c b/arch/arm/mach-imx/romapi.c new file mode 100644 index 0000000000..f7d421d737 --- /dev/null +++ b/arch/arm/mach-imx/romapi.c @@ -0,0 +1,44 @@ +#include <common.h> +#include <asm/sections.h> +#include <mach/romapi.h> +#include <mach/atf.h> + +static int imx8m_bootrom_load(struct rom_api *rom_api, void *adr, size_t size) +{ + while (size) { + size_t chunksize = min(size, (size_t)1024); + int ret; + + ret = rom_api->download_image(adr, 0, chunksize, + (uintptr_t)adr ^ chunksize); + if (ret != ROM_API_OKAY) { + pr_err("Failed to load piggy data (ret = %x)\n", ret); + return -EIO; + } + + adr += chunksize; + size -= chunksize; + } + + return 0; +} + +/* read piggydata via a bootrom callback and place it behind our copy in SDRAM */ +static int imx8m_bootrom_load_image(struct rom_api *rom_api) +{ + return imx8m_bootrom_load(rom_api, + (void *)MX8M_ATF_BL33_BASE_ADDR + barebox_pbl_size, + __piggydata_end - __piggydata_start); +} + +int imx8mp_bootrom_load_image(void) +{ + struct rom_api *rom_api = (void *)0x980; + + return imx8m_bootrom_load_image(rom_api); +} + +int imx8mn_bootrom_load_image(void) +{ + return imx8mp_bootrom_load_image(); +} |