summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-08-11 13:43:00 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-08-11 13:43:00 +0200
commit3fcf4400a7b051bdbe9fc175b88336519099ff22 (patch)
tree59e47312f23697970b3defc010a15f367b8e5082
parentb33c2913d747d3c55019a1d310427ca2697de6fc (diff)
parent22a073e3a9cdbc8034d5c58a6840e2567e5b3ddd (diff)
downloadbarebox-3fcf4400a7b051bdbe9fc175b88336519099ff22.tar.gz
barebox-3fcf4400a7b051bdbe9fc175b88336519099ff22.tar.xz
Merge branch 'for-next/imx'
-rw-r--r--Documentation/boards/imx/meerkat96.rst43
-rw-r--r--Documentation/boards/imx/nxp-imx8mp-evk.rst11
-rw-r--r--arch/arm/boards/Makefile1
-rw-r--r--arch/arm/boards/ls1046ardb/lowlevel.c6
-rw-r--r--arch/arm/boards/meerkat96/Makefile4
-rw-r--r--arch/arm/boards/meerkat96/board.c10
-rw-r--r--arch/arm/boards/meerkat96/flash-header-mx7-meerkat96.imxcfg105
-rw-r--r--arch/arm/boards/meerkat96/lowlevel.c34
-rw-r--r--arch/arm/boards/mnt-reform/lowlevel.c34
-rw-r--r--arch/arm/boards/mnt-reform/lpddr4-timing.c1
-rw-r--r--arch/arm/boards/nxp-imx8mm-evk/lowlevel.c103
-rw-r--r--arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c1
-rw-r--r--arch/arm/boards/nxp-imx8mn-evk/board.c21
-rw-r--r--arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c1
-rw-r--r--arch/arm/boards/nxp-imx8mn-evk/lowlevel.c153
-rw-r--r--arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c1
-rw-r--r--arch/arm/boards/nxp-imx8mp-evk/lowlevel.c99
-rw-r--r--arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c1
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/lowlevel.c4
-rw-r--r--arch/arm/boards/phytec-som-imx8mq/lowlevel.c4
-rw-r--r--arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c40
-rw-r--r--arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c1
-rw-r--r--arch/arm/configs/imx_v7_defconfig11
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/imx7d-meerkat96.dts42
-rw-r--r--arch/arm/dts/imx8mn-ddr4-evk.dts6
-rw-r--r--arch/arm/dts/imx8mn-evk.dts6
-rw-r--r--arch/arm/dts/imx8mn-evk.dtsi83
-rw-r--r--arch/arm/mach-imx/Kconfig9
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/atf.c144
-rw-r--r--arch/arm/mach-imx/include/mach/atf.h2
-rw-r--r--arch/arm/mach-imx/include/mach/romapi.h37
-rw-r--r--arch/arm/mach-imx/include/mach/xload.h4
-rw-r--r--arch/arm/mach-imx/romapi.c44
-rw-r--r--common/ddr_spd.c24
-rw-r--r--drivers/ddr/imx8m/ddr_init.c33
-rw-r--r--drivers/ddr/imx8m/ddrphy_train.c74
-rw-r--r--drivers/i2c/busses/i2c-imx-early.c21
-rw-r--r--drivers/mci/imx-esdhc-pbl.c2
-rw-r--r--drivers/net/fec_imx.c11
-rw-r--r--drivers/phy/phy-core.c11
-rw-r--r--drivers/usb/imx/chipidea-imx.c10
-rw-r--r--drivers/watchdog/imxwd.c18
-rw-r--r--images/Makefile.imx5
-rw-r--r--include/asm-generic/sections.h1
-rw-r--r--include/ddr_spd.h5
-rw-r--r--include/i2c/i2c-early.h13
-rw-r--r--include/pbl/i2c.h37
-rw-r--r--include/pbl/pmic.h41
-rw-r--r--include/soc/imx8m/ddr.h97
-rw-r--r--scripts/imx/imx-usb-loader.c175
52 files changed, 1079 insertions, 570 deletions
diff --git a/Documentation/boards/imx/meerkat96.rst b/Documentation/boards/imx/meerkat96.rst
new file mode 100644
index 0000000000..7456aa857b
--- /dev/null
+++ b/Documentation/boards/imx/meerkat96.rst
@@ -0,0 +1,43 @@
+Meerkat 96
+==========
+
+The Meerkat96 is a single board computer based on an i.MX7D SoC by NXP,
+featuring a dual core ARM Cortex-A7 at 1 GHz and a Cortex-M4 at 266MHz
+and 512 MB DRAM. For further details on the board's features check the
+manufacturers page at https://www.96boards.org/product/imx7-96
+
+Serial console
+--------------
+
+UART6 of the i.MX7D is broken out to Pinheader J3, on the Silkscreen
+the Pins are labeled with B (Ground), W (UART 6 TX) and G (UART 6 RX).
+If you use the UART-To-USB-Converter provided with the board, you can
+just connect the Black jumper to B, the White to W and the Green to G.
+
+The UART uses 3.3V levels.
+
+Building Barebox
+----------------
+
+To build Barebox for the meerkat96 board do the following:
+
+.. code-block:: sh
+
+ make ARCH=arm CROSS_COMPILE=<ARM toolchain prefix> mrproper
+ make ARCH=arm CROSS_COMPILE=<ARM toolchain prefix> imx_v7_defconfig
+ make ARCH=arm CROSS_COMPILE=<ARM toolchain prefix>
+
+Bringup
+-------
+
+flash the resulting barebox-meerkat96.img to an sdcard at address 0.
+
+Make sure the pmic is set to power-on state by setting the dipswitch
+SW3 on the boards bottom side to 1-1 (i.e. all switches on, which is
+the factory default).
+
+Schematics
+----------
+
+Schematics are available at https://github.com/96boards/documentation/blob/master/consumer/imx7-96/hardware-docs/files/iMX7-96-schematics.pdf
+
diff --git a/Documentation/boards/imx/nxp-imx8mp-evk.rst b/Documentation/boards/imx/nxp-imx8mp-evk.rst
index 366c1de500..1074992f2f 100644
--- a/Documentation/boards/imx/nxp-imx8mp-evk.rst
+++ b/Documentation/boards/imx/nxp-imx8mp-evk.rst
@@ -40,15 +40,18 @@ As a last step of this process those files need to be placed in
firmware/${f}; \
done
-Get and Build the ARM Trusted firmware
---------------------------------------
+Get and Build the Trusted Firmware A
+------------------------------------
-Get ATF from https://source.codeaurora.org/external/imx/imx-atf, branch
-imx_5.4.3_2.0.0::
+Get TF-A from https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/ and
+checkout version v2.7::
make PLAT=imx8mp bl31
cp build/imx8mp/release/bl31.bin ${barebox_srctree}/imx8mp-bl31.bin
+.. warning:: It is important to use a version >= v2.7 else your system
+ might not boot.
+
Build Barebox
-------------
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();
+}
diff --git a/common/ddr_spd.c b/common/ddr_spd.c
index 7089923afb..52773178e7 100644
--- a/common/ddr_spd.c
+++ b/common/ddr_spd.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <crc.h>
#include <ddr_spd.h>
+#include <pbl/i2c.h>
/* used for ddr1 and ddr2 spd */
static int spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
@@ -430,9 +431,7 @@ void ddr_spd_print(uint8_t *record)
#define SPD_SPA0_ADDRESS 0x36
#define SPD_SPA1_ADDRESS 0x37
-static int select_page(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
- uint8_t addr)
+static int select_page(struct pbl_i2c *i2c, uint8_t addr)
{
struct i2c_msg msg = {
.addr = addr,
@@ -440,15 +439,14 @@ static int select_page(void *ctx,
};
int ret;
- ret = xfer(ctx, &msg, 1);
+ ret = pbl_i2c_xfer(i2c, &msg, 1);
if (ret < 0)
return ret;
return 0;
}
-static int read_buf(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+static int read_buf(struct pbl_i2c *i2c,
uint8_t addr, int page, void *buf)
{
uint8_t pos = 0;
@@ -466,11 +464,11 @@ static int read_buf(void *ctx,
}
};
- ret = select_page(ctx, xfer, page);
+ ret = select_page(i2c, page);
if (ret < 0)
return ret;
- ret = xfer(ctx, msg, 2);
+ ret = pbl_i2c_xfer(i2c, msg, 2);
if (ret < 0)
return ret;
@@ -479,8 +477,7 @@ static int read_buf(void *ctx,
/**
* spd_read_eeprom - Read contents of a SPD EEPROM
- * @ctx: Context pointer for the xfer function
- * @xfer: I2C message transfer function
+ * @i2c: I2C controller handle
* @addr: I2C bus address for the EEPROM
* @buf: buffer to read the SPD data to
*
@@ -489,19 +486,18 @@ static int read_buf(void *ctx,
* have a size of 512 bytes. Returns 0 for success or a negative error code
* otherwise.
*/
-int spd_read_eeprom(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+int spd_read_eeprom(struct pbl_i2c *i2c,
uint8_t addr, void *buf)
{
unsigned char *buf8 = buf;
int ret;
- ret = read_buf(ctx, xfer, addr, SPD_SPA0_ADDRESS, buf);
+ ret = read_buf(i2c, addr, SPD_SPA0_ADDRESS, buf);
if (ret < 0)
return ret;
if (buf8[2] == SPD_MEMTYPE_DDR4) {
- ret = read_buf(ctx, xfer, addr, SPD_SPA1_ADDRESS, buf + 256);
+ ret = read_buf(i2c, addr, SPD_SPA1_ADDRESS, buf + 256);
if (ret < 0)
return ret;
}
diff --git a/drivers/ddr/imx8m/ddr_init.c b/drivers/ddr/imx8m/ddr_init.c
index 9a4b4e2ca8..18969ddb53 100644
--- a/drivers/ddr/imx8m/ddr_init.c
+++ b/drivers/ddr/imx8m/ddr_init.c
@@ -49,17 +49,18 @@ static void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
*/
#define IMX8M_SAVED_DRAM_TIMING_BASE 0x180000
-static int imx8m_ddr_init(struct dram_timing_info *dram_timing,
- enum ddrc_type type)
+int imx8m_ddr_init(struct dram_timing_info *dram_timing,
+ unsigned type)
{
unsigned long src_ddrc_rcr = MX8M_SRC_DDRC_RCR_ADDR;
unsigned int tmp, initial_drate, target_freq;
+ enum ddrc_type ddrc_type = get_ddrc_type(type);
int ret;
pr_debug("start DRAM init\n");
/* Step1: Follow the power up procedure */
- switch (type) {
+ switch (ddrc_type) {
case DDRC_TYPE_MQ:
reg32_write(src_ddrc_rcr + 0x04, 0x8f00000f);
reg32_write(src_ddrc_rcr, 0x8f00000f);
@@ -81,7 +82,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing,
initial_drate = dram_timing->fsp_msg[0].drate;
/* default to the frequency point 0 clock */
- ddrphy_init_set_dfi_clk(initial_drate, type);
+ ddrphy_init_set_dfi_clk(initial_drate, ddrc_type);
/* D-aasert the presetn */
reg32_write(src_ddrc_rcr, 0x8F000006);
@@ -107,7 +108,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing,
/* if ddr type is LPDDR4, do it */
tmp = reg32_read(DDRC_MSTR(0));
- if (tmp & (0x1 << 5) && type != DDRC_TYPE_MN)
+ if (tmp & (0x1 << 5) && ddrc_type != DDRC_TYPE_MN)
reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
/* determine the initial boot frequency */
@@ -154,7 +155,7 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing,
reg32_write(DDRC_SWCTL(0), 0x00000000);
/* Apply rank-to-rank workaround */
- update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, type);
+ update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, ddrc_type);
/* Step16: Set DFIMISC.dfi_init_start to 1 */
setbits_le32(DDRC_DFIMISC(0), (0x1 << 5));
@@ -210,23 +211,3 @@ static int imx8m_ddr_init(struct dram_timing_info *dram_timing,
return 0;
}
-
-int imx8mm_ddr_init(struct dram_timing_info *dram_timing)
-{
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM);
-}
-
-int imx8mn_ddr_init(struct dram_timing_info *dram_timing)
-{
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN);
-}
-
-int imx8mq_ddr_init(struct dram_timing_info *dram_timing)
-{
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ);
-}
-
-int imx8mp_ddr_init(struct dram_timing_info *dram_timing)
-{
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP);
-}
diff --git a/drivers/ddr/imx8m/ddrphy_train.c b/drivers/ddr/imx8m/ddrphy_train.c
index 9dc20a4762..e9d35afdfb 100644
--- a/drivers/ddr/imx8m/ddrphy_train.c
+++ b/drivers/ddr/imx8m/ddrphy_train.c
@@ -11,6 +11,48 @@
#include <firmware.h>
#include <mach/imx8m-regs.h>
+static const u16 *lpddr4_imem_1d;
+static size_t lpddr4_imem_1d_size;
+static const u16 *lpddr4_dmem_1d;
+static size_t lpddr4_dmem_1d_size;
+static const u16 *lpddr4_imem_2d;
+static size_t lpddr4_imem_2d_size;
+static const u16 *lpddr4_dmem_2d;
+static size_t lpddr4_dmem_2d_size;
+
+void ddr_get_firmware_lpddr4(void)
+{
+ get_builtin_firmware(lpddr4_pmu_train_1d_imem_bin, &lpddr4_imem_1d,
+ &lpddr4_imem_1d_size);
+ get_builtin_firmware(lpddr4_pmu_train_1d_dmem_bin, &lpddr4_dmem_1d,
+ &lpddr4_dmem_1d_size);
+ get_builtin_firmware(lpddr4_pmu_train_2d_imem_bin, &lpddr4_imem_2d,
+ &lpddr4_imem_2d_size);
+ get_builtin_firmware(lpddr4_pmu_train_2d_dmem_bin, &lpddr4_dmem_2d,
+ &lpddr4_dmem_2d_size);
+}
+
+static const u16 *ddr4_imem_1d;
+static size_t ddr4_imem_1d_size;
+static const u16 *ddr4_dmem_1d;
+static size_t ddr4_dmem_1d_size;
+static const u16 *ddr4_imem_2d;
+static size_t ddr4_imem_2d_size;
+static const u16 *ddr4_dmem_2d;
+static size_t ddr4_dmem_2d_size;
+
+void ddr_get_firmware_ddr(void)
+{
+ get_builtin_firmware(ddr4_imem_1d_bin, &ddr4_imem_1d,
+ &ddr4_imem_1d_size);
+ get_builtin_firmware(ddr4_dmem_1d_bin, &ddr4_dmem_1d,
+ &ddr4_dmem_1d_size);
+ get_builtin_firmware(ddr4_imem_2d_bin, &ddr4_imem_2d,
+ &ddr4_imem_2d_size);
+ get_builtin_firmware(ddr4_dmem_2d_bin, &ddr4_dmem_2d,
+ &ddr4_dmem_2d_size);
+}
+
void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type)
{
const u16 *imem, *dmem;
@@ -18,19 +60,27 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type)
if (dram_is_lpddr4(dram_type)) {
if (fw_type == FW_1D_IMAGE) {
- get_builtin_firmware(lpddr4_pmu_train_1d_imem_bin, &imem, &isize);
- get_builtin_firmware(lpddr4_pmu_train_1d_dmem_bin, &dmem, &dsize);
+ imem = lpddr4_imem_1d;
+ isize = lpddr4_imem_1d_size;
+ dmem = lpddr4_dmem_1d;
+ dsize = lpddr4_dmem_1d_size;
} else {
- get_builtin_firmware(lpddr4_pmu_train_2d_imem_bin, &imem, &isize);
- get_builtin_firmware(lpddr4_pmu_train_2d_dmem_bin, &dmem, &dsize);
+ imem = lpddr4_imem_2d;
+ isize = lpddr4_imem_2d_size;
+ dmem = lpddr4_dmem_2d;
+ dsize = lpddr4_dmem_2d_size;
}
} else if (dram_is_ddr4(dram_type)) {
if (fw_type == FW_1D_IMAGE) {
- get_builtin_firmware(ddr4_imem_1d_bin, &imem, &isize);
- get_builtin_firmware(ddr4_dmem_1d_bin, &dmem, &dsize);
+ imem = ddr4_imem_1d;
+ isize = ddr4_imem_1d_size;
+ dmem = ddr4_dmem_1d;
+ dsize = ddr4_dmem_1d_size;
} else {
- get_builtin_firmware(ddr4_imem_2d_bin, &imem, &isize);
- get_builtin_firmware(ddr4_dmem_2d_bin, &dmem, &dsize);
+ imem = ddr4_imem_2d;
+ isize = ddr4_imem_2d_size;
+ dmem = ddr4_dmem_2d;
+ dsize = ddr4_dmem_2d_size;
}
} else {
panic("No matching DDR PHY firmware found");
@@ -43,8 +93,10 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type)
DDRC_PHY_DMEM, dmem, dsize);
}
-int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type)
+int ddr_cfg_phy(struct dram_timing_info *dram_timing, unsigned type)
{
+ enum ddrc_type ddrc_type = get_ddrc_type(type);
+ enum dram_type dram_type = get_dram_type(type);
struct dram_cfg_param *dram_cfg;
struct dram_fsp_msg *fsp_msg;
unsigned int num;
@@ -66,11 +118,11 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type)
for (i = 0; i < dram_timing->fsp_msg_num; i++) {
pr_debug("DRAM PHY training for %dMTS\n", fsp_msg->drate);
/* set dram PHY input clocks to desired frequency */
- ddrphy_init_set_dfi_clk(fsp_msg->drate, type);
+ ddrphy_init_set_dfi_clk(fsp_msg->drate, ddrc_type);
/* load the dram training firmware image */
dwc_ddrphy_apb_wr(0xd0000, 0x0);
- ddr_load_train_code(dram_timing->dram_type, fsp_msg->fw_type);
+ ddr_load_train_code(dram_type, fsp_msg->fw_type);
/* load the frequency set point message block parameter */
dram_cfg = fsp_msg->fsp_cfg;
diff --git a/drivers/i2c/busses/i2c-imx-early.c b/drivers/i2c/busses/i2c-imx-early.c
index a79d7bd88c..4e0f7e517d 100644
--- a/drivers/i2c/busses/i2c-imx-early.c
+++ b/drivers/i2c/busses/i2c-imx-early.c
@@ -9,11 +9,12 @@
*/
#include <common.h>
#include <i2c/i2c.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include "i2c-imx.h"
struct fsl_i2c {
+ struct pbl_i2c i2c;
void __iomem *regs;
unsigned int i2cr_ien_opcode;
unsigned int i2sr_clr_opcode;
@@ -170,7 +171,7 @@ static int i2c_fsl_write(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
/* write data */
for (i = 0; i < msg->len; i++) {
ret = i2c_fsl_send(fsl_i2c, msg->buf[i]);
- if (ret)
+ if (ret)
return ret;
}
@@ -229,9 +230,9 @@ static int i2c_fsl_read(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
* If successful returns the number of messages transferred, otherwise a negative
* error code is returned.
*/
-int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num)
+static int i2c_fsl_xfer(struct pbl_i2c *i2c, struct i2c_msg *msgs, int num)
{
- struct fsl_i2c *fsl_i2c = ctx;
+ struct fsl_i2c *fsl_i2c = container_of(i2c, struct fsl_i2c, i2c);
unsigned int i, temp;
int ret;
@@ -288,7 +289,7 @@ static struct fsl_i2c fsl_i2c;
* This function returns a context pointer suitable to transfer I2C messages
* using i2c_fsl_xfer.
*/
-void *ls1046_i2c_init(void __iomem *regs)
+struct pbl_i2c *ls1046_i2c_init(void __iomem *regs)
{
fsl_i2c.regs = regs;
fsl_i2c.regshift = 0;
@@ -297,10 +298,12 @@ void *ls1046_i2c_init(void __iomem *regs)
/* Divider for ~100kHz when coming from the ROM */
fsl_i2c.ifdr = 0x3e;
- return &fsl_i2c;
+ fsl_i2c.i2c.xfer = i2c_fsl_xfer;
+
+ return &fsl_i2c.i2c;
}
-void *imx8m_i2c_early_init(void __iomem *regs)
+struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs)
{
fsl_i2c.regs = regs;
fsl_i2c.regshift = 2;
@@ -309,5 +312,7 @@ void *imx8m_i2c_early_init(void __iomem *regs)
/* Divider for ~100kHz when coming from the ROM */
fsl_i2c.ifdr = 0x0f;
- return &fsl_i2c;
+ fsl_i2c.i2c.xfer = i2c_fsl_xfer;
+
+ return &fsl_i2c.i2c;
}
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 5a76e7a663..c81eba5b9d 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -44,7 +44,7 @@ static int esdhc_send_ext_csd(struct fsl_esdhc_host *host)
return esdhc_send_cmd(host, &cmd, &data);
}
-static bool esdhc_bootpart_active(struct fsl_esdhc_host *host)
+static bool __maybe_unused esdhc_bootpart_active(struct fsl_esdhc_host *host)
{
unsigned bootpart;
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 0c2d600d12..673555a48a 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -320,6 +320,10 @@ static int fec_init(struct eth_device *dev)
/* size of each buffer */
writel(FEC_MAX_PKT_SIZE, fec->regs + FEC_EMRBR);
+ /* set rx and tx buffer descriptor base address */
+ writel(virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR);
+ writel(virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR);
+
return 0;
}
@@ -359,6 +363,8 @@ static int fec_open(struct eth_device *edev)
if (fec->phy_init)
fec->phy_init(edev->phydev);
+ fec_init(edev);
+
/*
* Initialize RxBD/TxBD rings
*/
@@ -839,9 +845,6 @@ static int fec_probe(struct device_d *dev)
base += FEC_RBD_NUM * sizeof(struct buffer_descriptor);
fec->tbd_base = base;
- writel(virt_to_phys(fec->tbd_base), fec->regs + FEC_ETDSR);
- writel(virt_to_phys(fec->rbd_base), fec->regs + FEC_ERDSR);
-
ret = fec_alloc_receive_packets(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
if (ret < 0)
goto free_xbd;
@@ -861,8 +864,6 @@ static int fec_probe(struct device_d *dev)
if (ret)
goto free_receive_packets;
- fec_init(edev);
-
fec->miibus.read = fec_miibus_read;
fec->miibus.write = fec_miibus_write;
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index b298da0000..8a57bd1aa9 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -220,6 +220,11 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
{
struct phy_provider *phy_provider;
struct device_node *child;
+ int ret;
+
+ ret = of_device_ensure_probed(node);
+ if (ret)
+ return ERR_PTR(ret);
list_for_each_entry(phy_provider, &phy_provider_list, list) {
if (phy_provider->dev->device_node == node)
@@ -255,10 +260,6 @@ static struct phy *_of_phy_get(struct device_node *np, int index)
if (ret)
return ERR_PTR(-ENODEV);
- ret = of_device_ensure_probed(args.np);
- if (ret)
- return ERR_PTR(ret);
-
phy_provider = of_phy_provider_lookup(args.np);
if (IS_ERR(phy_provider)) {
return ERR_CAST(phy_provider);
@@ -316,7 +317,7 @@ struct phy *of_phy_get_by_phandle(struct device_d *dev, const char *phandle,
phy_provider = of_phy_provider_lookup(np);
if (IS_ERR(phy_provider)) {
- return ERR_PTR(-ENODEV);
+ return ERR_CAST(phy_provider);
}
return phy_provider->of_xlate(phy_provider->dev, NULL);
diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c
index bf8b6f1eb8..f71cf80b7d 100644
--- a/drivers/usb/imx/chipidea-imx.c
+++ b/drivers/usb/imx/chipidea-imx.c
@@ -260,8 +260,6 @@ static int imx_chipidea_probe(struct device_d *dev)
* devices which have only one.
*/
ci->clk = clk_get(dev, NULL);
- if (!IS_ERR(ci->clk))
- clk_enable(ci->clk);
/* Device trees are using both "phys" and "fsl,usbphy". Prefer the
* more modern former one but fall back to the old one.
@@ -302,6 +300,14 @@ static int imx_chipidea_probe(struct device_d *dev)
ci->data.drvdata = ci;
ci->data.usbphy = ci->usbphy;
+ /*
+ * Enable the clock after we ensured that all resources are available.
+ * This is crucial since the phy can be missing which and so the
+ * usb-controller <-> usb-phy communication is only partly initialized.
+ * This can trigger strange system hangs at least on i.MX8M SoCs.
+ */
+ clk_enable(ci->clk);
+
if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_HSIC)
imx_chipidea_port_init(ci);
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 31ea388c2c..dba92cb46a 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -239,18 +239,17 @@ static int imx_wd_probe(struct device_d *dev)
priv = xzalloc(sizeof(struct imx_wd));
iores = dev_request_mem_resource(dev, 0);
- if (IS_ERR(iores)) {
- dev_err(dev, "could not get memory region\n");
- return PTR_ERR(iores);
- }
+ if (IS_ERR(iores))
+ return dev_err_probe(dev, PTR_ERR(iores),
+ "could not get memory region\n");
clk = clk_get(dev, NULL);
if (IS_ERR(clk))
- return PTR_ERR(clk);
+ return dev_err_probe(dev, PTR_ERR(clk), "Failed to get clk\n");
ret = clk_enable(clk);
if (ret)
- return ret;
+ return dev_err_probe(dev, ret, "Failed to enable clk\n");
priv->base = IOMEM(iores->start);
priv->ops = ops;
@@ -272,14 +271,17 @@ static int imx_wd_probe(struct device_d *dev)
}
ret = watchdog_register(&priv->wd);
- if (ret)
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to register watchdog device\n");
goto on_error;
+ }
}
if (priv->ops->init) {
ret = priv->ops->init(priv);
if (ret) {
- dev_err(dev, "Failed to init watchdog device %d\n", ret);
+ dev_err_probe(dev, ret,
+ "Failed to init watchdog device\n");
goto error_unregister;
}
}
diff --git a/images/Makefile.imx b/images/Makefile.imx
index 62549ab758..a19e0ff1c7 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -418,6 +418,11 @@ CFG_start_zii_imx7d_dev.pblb.imximg = $(board)/zii-imx7d-dev/flash-header-zii-im
FILE_barebox-zii-imx7d-dev.img = start_zii_imx7d_dev.pblb.imximg
image-$(CONFIG_MACH_ZII_IMX7D_DEV) += barebox-zii-imx7d-dev.img
+pblb-$(CONFIG_MACH_MEERKAT96) += start_imx7d_meerkat96
+CFG_start_imx7d_meerkat96.pblb.imximg = $(board)/meerkat96/flash-header-mx7-meerkat96.imxcfg
+FILE_barebox-meerkat96.img = start_imx7d_meerkat96.pblb.imximg
+image-$(CONFIG_MACH_MEERKAT96) += barebox-meerkat96.img
+
pblb-$(CONFIG_MACH_KAMSTRUP_MX7_CONCENTRATOR) += start_kamstrup_mx7_concentrator
CFG_start_kamstrup_mx7_concentrator.pblb.imximg = $(board)/kamstrup-mx7-concentrator/flash-header-tqma7d.imxcfg
FILE_barebox-kamstrup-mx7-concentrator.img = start_kamstrup_mx7_concentrator.pblb.imximg
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 0b2ed5615b..e54123de0e 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -11,6 +11,7 @@ extern char _end[];
extern char __image_start[];
extern char __image_end[];
extern char __piggydata_start[];
+extern char __piggydata_end[];
extern void *_barebox_image_size;
extern void *_barebox_bare_init_size;
extern void *_barebox_pbl_size;
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
index 6e63d90e5e..bcc2171d2a 100644
--- a/include/ddr_spd.h
+++ b/include/ddr_spd.h
@@ -6,7 +6,7 @@
#ifndef _DDR_SPD_H_
#define _DDR_SPD_H_
-#include <i2c/i2c.h>
+#include <pbl/i2c.h>
/*
* Format from "JEDEC Standard No. 21-C,
@@ -574,8 +574,7 @@ void ddr2_spd_dump(const struct ddr2_spd_eeprom *spd);
int ddr3_spd_check(const struct ddr3_spd_eeprom *spd);
int ddr4_spd_check(const struct ddr4_spd_eeprom *spd);
-int spd_read_eeprom(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+int spd_read_eeprom(struct pbl_i2c *i2c,
uint8_t addr, void *buf);
#endif /* _DDR_SPD_H_ */
diff --git a/include/i2c/i2c-early.h b/include/i2c/i2c-early.h
deleted file mode 100644
index fa93656e28..0000000000
--- a/include/i2c/i2c-early.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef __I2C_EARLY_H
-#define __I2C_EARLY_H
-
-#include <i2c/i2c.h>
-
-int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num);
-
-void *imx8m_i2c_early_init(void __iomem *regs);
-void *ls1046_i2c_init(void __iomem *regs);
-
-#endif /* __I2C_EARLY_H */
diff --git a/include/pbl/i2c.h b/include/pbl/i2c.h
new file mode 100644
index 0000000000..d9910f531f
--- /dev/null
+++ b/include/pbl/i2c.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __PBL_I2C_H
+#define __PBL_I2C_H
+
+#include <i2c/i2c.h>
+
+struct pbl_i2c {
+ int (*xfer)(struct pbl_i2c *, struct i2c_msg *msgs, int num);
+};
+
+static inline int pbl_i2c_xfer(struct pbl_i2c *i2c,
+ struct i2c_msg *msgs, int num)
+{
+ return i2c->xfer(i2c, msgs, num);
+}
+
+struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs);
+struct pbl_i2c *ls1046_i2c_init(void __iomem *regs);
+
+static inline int i2c_dev_probe(struct pbl_i2c *i2c, int addr, bool onebyte)
+{
+ u8 buf[1];
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ .buf = buf,
+ .flags = I2C_M_RD,
+ .len = onebyte,
+ },
+ };
+
+ return pbl_i2c_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
+}
+
+
+#endif /* __I2C_EARLY_H */
diff --git a/include/pbl/pmic.h b/include/pbl/pmic.h
new file mode 100644
index 0000000000..0f882c5649
--- /dev/null
+++ b/include/pbl/pmic.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PBL_PMIC_H_
+#define __PBL_PMIC_H_
+
+#include <pbl/i2c.h>
+
+struct pmic_config {
+ u8 reg;
+ u8 val;
+};
+
+static void pmic_reg_write(struct pbl_i2c *i2c, int addr, u8 reg, u8 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 = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret != 1)
+ pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
+}
+
+static inline void pmic_configure(struct pbl_i2c *i2c, u8 addr,
+ const struct pmic_config *config,
+ size_t config_len)
+{
+ for (; config_len--; config++)
+ pmic_reg_write(i2c, addr, config->reg, config->val);
+}
+
+#endif
diff --git a/include/soc/imx8m/ddr.h b/include/soc/imx8m/ddr.h
index c81c4d82c5..2149ae4325 100644
--- a/include/soc/imx8m/ddr.h
+++ b/include/soc/imx8m/ddr.h
@@ -329,10 +329,29 @@ enum fw_type {
};
enum dram_type {
- DRAM_TYPE_LPDDR4,
- DRAM_TYPE_DDR4,
+#define DRAM_TYPE_MASK 0x00ff
+ DRAM_TYPE_LPDDR4 = 0 << 0,
+ DRAM_TYPE_DDR4 = 1 << 0,
};
+static inline enum dram_type get_dram_type(unsigned type)
+{
+ return type & DRAM_TYPE_MASK;
+}
+
+enum ddrc_type {
+#define DDRC_TYPE_MASK 0xff00
+ DDRC_TYPE_MM = 0 << 8,
+ DDRC_TYPE_MN = 1 << 8,
+ DDRC_TYPE_MQ = 2 << 8,
+ DDRC_TYPE_MP = 3 << 8,
+};
+
+static inline enum ddrc_type get_ddrc_type(unsigned type)
+{
+ return type & DDRC_TYPE_MASK;
+}
+
struct dram_cfg_param {
unsigned int reg;
unsigned int val;
@@ -346,7 +365,6 @@ struct dram_fsp_msg {
};
struct dram_timing_info {
- enum dram_type dram_type;
/* umctl2 config */
struct dram_cfg_param *ddrc_cfg;
unsigned int ddrc_cfg_num;
@@ -368,29 +386,64 @@ struct dram_timing_info {
extern struct dram_timing_info dram_timing;
-enum ddrc_type {
- DDRC_TYPE_MM,
- DDRC_TYPE_MN,
- DDRC_TYPE_MQ,
- DDRC_TYPE_MP,
-};
+void ddr_get_firmware_lpddr4(void);
+void ddr_get_firmware_ddr(void);
+
+static void ddr_get_firmware(enum dram_type dram_type)
+{
+ if (dram_type == DRAM_TYPE_LPDDR4)
+ ddr_get_firmware_lpddr4();
+ else
+ ddr_get_firmware_ddr();
+}
+
+int imx8m_ddr_init(struct dram_timing_info *dram_timing,
+ unsigned type);
+
+static inline int imx8mm_ddr_init(struct dram_timing_info *dram_timing,
+ enum dram_type dram_type)
+{
+ ddr_get_firmware(dram_type);
+
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM | dram_type);
+}
+
+static inline int imx8mn_ddr_init(struct dram_timing_info *dram_timing,
+ enum dram_type dram_type)
+{
+ ddr_get_firmware(dram_type);
+
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN | dram_type);
+}
+
+static inline int imx8mq_ddr_init(struct dram_timing_info *dram_timing,
+ enum dram_type dram_type)
+{
+ ddr_get_firmware(dram_type);
+
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ | dram_type);
+}
+
+static inline int imx8mp_ddr_init(struct dram_timing_info *dram_timing,
+ enum dram_type dram_type)
+{
+ ddr_get_firmware(dram_type);
+
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP | dram_type);
+}
-int imx8mm_ddr_init(struct dram_timing_info *timing_info);
-int imx8mn_ddr_init(struct dram_timing_info *timing_info);
-int imx8mq_ddr_init(struct dram_timing_info *timing_info);
-int imx8mp_ddr_init(struct dram_timing_info *timing_info);
-int ddr_cfg_phy(struct dram_timing_info *timing_info, enum ddrc_type type);
+int ddr_cfg_phy(struct dram_timing_info *timing_info, enum ddrc_type ddrc_type);
void load_lpddr4_phy_pie(void);
void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num);
void dram_config_save(struct dram_timing_info *info, unsigned long base);
/* utils function for ddr phy training */
int wait_ddrphy_training_complete(void);
-void ddrphy_init_set_dfi_clk(unsigned int drate, enum ddrc_type type);
-void ddrphy_init_read_msg_block(enum fw_type type);
+void ddrphy_init_set_dfi_clk(unsigned int drate, enum ddrc_type ddrc_type);
+void ddrphy_init_read_msg_block(enum fw_type fw_type);
void update_umctl2_rank_space_setting(unsigned int pstat_num,
- enum ddrc_type type);
+ enum ddrc_type ddrc_type);
void get_trained_CDD(unsigned int fsp);
#define reg32_write(a, v) writel(v, a)
@@ -415,22 +468,22 @@ enum ddrc_phy_firmware_offset {
DDRC_PHY_DMEM = 0x00054000U,
};
-void ddr_load_train_code(enum dram_type dram_type, enum fw_type type);
+void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type);
void ddrc_phy_load_firmware(void __iomem *,
enum ddrc_phy_firmware_offset,
const u16 *, size_t);
-static inline bool dram_is_lpddr4(enum dram_type type)
+static inline bool dram_is_lpddr4(enum dram_type dram_type)
{
return IS_ENABLED(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) &&
- type == DRAM_TYPE_LPDDR4;
+ dram_type == DRAM_TYPE_LPDDR4;
}
-static inline bool dram_is_ddr4(enum dram_type type)
+static inline bool dram_is_ddr4(enum dram_type dram_type)
{
return IS_ENABLED(CONFIG_FIRMWARE_IMX_DDR4_PMU_TRAIN) &&
- type == DRAM_TYPE_DDR4;
+ dram_type == DRAM_TYPE_DDR4;
}
#define DDRC_PHY_REG(x) ((x) * 4)
diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
index 69df9bbe92..1242f2dedd 100644
--- a/scripts/imx/imx-usb-loader.c
+++ b/scripts/imx/imx-usb-loader.c
@@ -74,6 +74,7 @@ struct mach_id {
#define DEV_IMX 0
#define DEV_MXS 1
unsigned char dev_type;
+ unsigned char hid_endpoint;
};
struct usb_work {
@@ -182,6 +183,22 @@ static const struct mach_id imx_ids[] = {
.max_transfer = 1024,
}, {
.vid = 0x1fc9,
+ .pid = 0x0146,
+ .name = "i.MX8MP",
+ .header_type = HDR_MX53,
+ .max_transfer = 1020,
+ .mode = MODE_HID,
+ .hid_endpoint = 1,
+ }, {
+ .vid = 0x1fc9,
+ .pid = 0x013e,
+ .name = "i.MX8MN",
+ .header_type = HDR_MX53,
+ .max_transfer = 1020,
+ .dev_type = MODE_HID,
+ .hid_endpoint = 1,
+ }, {
+ .vid = 0x1fc9,
.pid = 0x012b,
.name = "i.MX8MQ",
.header_type = HDR_MX53,
@@ -447,7 +464,7 @@ static void dump_bytes(const void *src, unsigned cnt, unsigned addr)
* EP2IN - bulk in
* (max packet size of 512 bytes)
*/
-static int transfer(int report, unsigned char *p, unsigned cnt, int *last_trans)
+static int transfer(int report, void *p, unsigned cnt, int *last_trans)
{
int err;
if (cnt > mach_id->max_transfer)
@@ -470,15 +487,22 @@ static int transfer(int report, unsigned char *p, unsigned cnt, int *last_trans)
if (report < 3) {
memcpy(&tmp[1], p, cnt);
- err = libusb_control_transfer(usb_dev_handle,
- CTRL_OUT,
- HID_SET_REPORT,
- (HID_REPORT_TYPE_OUTPUT << 8) | report,
- 0,
- tmp, cnt + 1, 1000);
- *last_trans = (err > 0) ? err - 1 : 0;
- if (err > 0)
- err = 0;
+ if (mach_id->hid_endpoint) {
+ int trans;
+ err = libusb_interrupt_transfer(usb_dev_handle,
+ mach_id->hid_endpoint, tmp, cnt + 1, &trans, 1000);
+ *last_trans = trans - 1;
+ } else {
+ err = libusb_control_transfer(usb_dev_handle,
+ CTRL_OUT,
+ HID_SET_REPORT,
+ (HID_REPORT_TYPE_OUTPUT << 8) | report,
+ 0,
+ tmp, cnt + 1, 1000);
+ *last_trans = (err > 0) ? err - 1 : 0;
+ if (err > 0)
+ err = 0;
+ }
} else {
*last_trans = 0;
memset(&tmp[1], 0, cnt);
@@ -511,7 +535,7 @@ static int do_status(void)
unsigned char tmp[64];
int retry = 0;
int err;
- static const struct sdp_command status_command = {
+ static struct sdp_command status_command = {
.cmd = SDP_ERROR_STATUS,
.addr = 0,
.format = 0,
@@ -521,8 +545,7 @@ static int do_status(void)
};
for (;;) {
- err = transfer(1, (unsigned char *) &status_command, 16,
- &last_trans);
+ err = transfer(1, &status_command, 16, &last_trans);
if (verbose > 2)
printf("report 1, wrote %i bytes, err=%i\n", last_trans, err);
@@ -575,8 +598,7 @@ static int read_memory(unsigned addr, void *dest, unsigned cnt)
read_reg_command.cnt = htonl(cnt);
for (;;) {
- err = transfer(1, (unsigned char *) &read_reg_command, 16,
- &last_trans);
+ err = transfer(1, &read_reg_command, 16, &last_trans);
if (!err)
break;
printf("read_reg_command err=%i, last_trans=%i\n", err, last_trans);
@@ -603,17 +625,10 @@ static int read_memory(unsigned addr, void *dest, unsigned cnt)
err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3], cnt, rem);
break;
}
- if ((last_trans > rem) || (last_trans > 64)) {
- if ((last_trans == 64) && (rem < 64)) {
- /* Last transfer is expected to be too large for HID */
- } else {
- printf("err: %02x %02x %02x %02x cnt=%u rem=%d last_trans=%i\n",
- tmp[0], tmp[1], tmp[2], tmp[3], cnt, rem, last_trans);
- }
+
+ if (last_trans > rem)
last_trans = rem;
- if (last_trans > 64)
- last_trans = 64;
- }
+
memcpy(dest, tmp, last_trans);
dest += last_trans;
rem -= last_trans;
@@ -659,8 +674,7 @@ static int write_memory(unsigned addr, unsigned val, int width)
write_reg_command.data = htonl(val);
for (;;) {
- err = transfer(1, (unsigned char *) &write_reg_command, 16,
- &last_trans);
+ err = transfer(1, &write_reg_command, 16, &last_trans);
if (!err)
break;
printf("write_reg_command err=%i, last_trans=%i\n", err, last_trans);
@@ -713,6 +727,31 @@ static int modify_memory(unsigned addr, unsigned val, int width, int set_bits, i
return write_memory(addr, val, 4);
}
+static int send_buf(void *buf, unsigned len)
+{
+ void *p = buf;
+ int cnt = len;
+ int err;
+
+ while (1) {
+ int now = get_min(cnt, mach_id->max_transfer);
+
+ if (!now)
+ break;
+
+ err = transfer(2, p, now, &now);
+ if (err) {
+ printf("dl_command err=%i, last_trans=%i\n", err, now);
+ return err;
+ }
+
+ p += now;
+ cnt -= now;
+ }
+
+ return 0;
+}
+
static int load_file(void *buf, unsigned len, unsigned dladdr,
unsigned char type, bool mode_barebox)
{
@@ -729,8 +768,6 @@ static int load_file(void *buf, unsigned len, unsigned dladdr,
int retry = 0;
unsigned transfer_size = 0;
unsigned char tmp[64];
- void *p;
- int cnt;
len = ALIGN(len, 4);
@@ -739,8 +776,7 @@ static int load_file(void *buf, unsigned len, unsigned dladdr,
dl_command.rsvd = type;
for (;;) {
- err = transfer(1, (unsigned char *) &dl_command, 16,
- &last_trans);
+ err = transfer(1, &dl_command, 16, &last_trans);
if (!err)
break;
@@ -760,24 +796,9 @@ static int load_file(void *buf, unsigned len, unsigned dladdr,
err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
}
- p = buf;
- cnt = len;
-
- while (1) {
- int now = get_min(cnt, mach_id->max_transfer);
-
- if (!now)
- break;
-
- err = transfer(2, p, now, &now);
- if (err) {
- printf("dl_command err=%i, last_trans=%i\n", err, last_trans);
- return err;
- }
-
- p += now;
- cnt -= now;
- }
+ err = send_buf(buf, len);
+ if (err)
+ return err;
if (mode_barebox)
return transfer_size;
@@ -815,8 +836,7 @@ static int sdp_jump_address(unsigned addr)
jump_command.addr = htonl(addr);
for (;;) {
- err = transfer(1, (unsigned char *) &jump_command, 16,
- &last_trans);
+ err = transfer(1, &jump_command, 16, &last_trans);
if (!err)
break;
@@ -1234,19 +1254,22 @@ static int get_dl_start(const unsigned char *p, const unsigned char *file_start,
}
case HDR_MX53:
{
- unsigned char *bd;
+ unsigned char *_bd;
struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p;
+ struct imx_boot_data *bd;
*header_addr = hdr->self;
- bd = hdr->boot_data_ptr + cvt_dest_to_src;
- if ((bd < file_start) || ((bd + 4) > file_end)) {
+ _bd = hdr->boot_data_ptr + cvt_dest_to_src;
+ if ((_bd < file_start) || ((_bd + 4) > file_end)) {
printf("bad boot_data_ptr %08x\n", hdr->boot_data_ptr);
return -1;
}
- *firststage_len = ((struct imx_boot_data *)bd)->size;
- *plugin = ((struct imx_boot_data *)bd)->plugin;
- ((struct imx_boot_data *)bd)->plugin = 0;
+ bd = (void *)_bd;
+
+ *firststage_len = bd->size - (hdr->self - bd->start);
+ *plugin = bd->plugin;
+ bd->plugin = 0;
break;
}
@@ -1345,6 +1368,9 @@ static int do_irom_download(struct usb_work *curr, int verify)
header_offset = ret;
+ if (mach_id->hid_endpoint)
+ return send_buf(buf + header_offset, fsize - header_offset);
+
if (plugin && (!curr->plug)) {
printf("Only plugin header found\n");
ret = -1;
@@ -1386,7 +1412,7 @@ static int do_irom_download(struct usb_work *curr, int verify)
if (verify) {
printf("verifying file...\n");
- ret = verify_memory(image, fsize, header_addr);
+ ret = verify_memory(image, firststage_len, header_addr);
if (ret < 0) {
printf("verifying failed\n");
goto cleanup;
@@ -1442,13 +1468,10 @@ static int write_mem(const struct config_data *data, uint32_t addr,
return modify_memory(addr, val, width, set_bits, clear_bits);
}
-/* MXS section */
-static int mxs_load_file(libusb_device_handle *dev, uint8_t *data, int size)
+static int mxs_load_buf(uint8_t *data, int size)
{
static struct mxs_command dl_command;
int last_trans, err;
- void *p;
- int cnt;
dl_command.sign = htonl(0x424c5443); /* Signature: BLTC */
dl_command.tag = htonl(0x1);
@@ -1459,36 +1482,19 @@ static int mxs_load_file(libusb_device_handle *dev, uint8_t *data, int size)
dl_command.cmd = MXS_CMD_FW_DOWNLOAD;
dl_command.dw_size = htonl(size);
- err = transfer(1, (unsigned char *) &dl_command, 20, &last_trans);
+ err = transfer(1, &dl_command, 20, &last_trans);
if (err) {
printf("transfer error at init step: err=%i, last_trans=%i\n",
err, last_trans);
return err;
}
- p = data;
- cnt = size;
-
- while (1) {
- int now = get_min(cnt, mach_id->max_transfer);
-
- if (!now)
- break;
-
- err = transfer(2, p, now, &now);
- if (err) {
- printf("dl_command err=%i, last_trans=%i\n", err, now);
- return err;
- }
-
- p += now;
- cnt -= now;
- }
+ err = send_buf(data, size);
return err;
}
-static int mxs_work(struct usb_work *curr)
+static int mxs_load_file(struct usb_work *curr)
{
size_t fsize = 0;
unsigned char *buf = NULL;
@@ -1497,9 +1503,8 @@ static int mxs_work(struct usb_work *curr)
if (!buf)
return -errno;
- return mxs_load_file(usb_dev_handle, buf, fsize);
+ return mxs_load_buf(buf, fsize);
}
-/* end of mxs section */
static int parse_initfile(const char *filename)
{
@@ -1619,7 +1624,7 @@ int main(int argc, char *argv[])
}
if (mach_id->dev_type == DEV_MXS) {
- ret = mxs_work(&w);
+ ret = mxs_load_file(&w);
goto out;
}