summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/nxp-imx8mq-evk
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/nxp-imx8mq-evk')
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/.gitignore2
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/Makefile2
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/board.c28
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/ddr.h9
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/ddr_init.c3
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c14
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg7
-rw-r--r--arch/arm/boards/nxp-imx8mq-evk/lowlevel.c94
8 files changed, 52 insertions, 107 deletions
diff --git a/arch/arm/boards/nxp-imx8mq-evk/.gitignore b/arch/arm/boards/nxp-imx8mq-evk/.gitignore
index ef13747c92..cafa52b207 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/.gitignore
+++ b/arch/arm/boards/nxp-imx8mq-evk/.gitignore
@@ -1 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
*.ddr-phy-fw*
diff --git a/arch/arm/boards/nxp-imx8mq-evk/Makefile b/arch/arm/boards/nxp-imx8mq-evk/Makefile
index 2995f06f0f..17d769f330 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/Makefile
+++ b/arch/arm/boards/nxp-imx8mq-evk/Makefile
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
obj-y += board.o
lwl-y += lowlevel.o ddr_init.o ddrphy_train.o
diff --git a/arch/arm/boards/nxp-imx8mq-evk/board.c b/arch/arm/boards/nxp-imx8mq-evk/board.c
index 299d056e27..d86666958a 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/board.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/board.c
@@ -1,21 +1,5 @@
-/*
- * Copyright (C) 2018 Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation.
- *
- */
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2018 Sascha Hauer, Pengutronix
#include <asm/memory.h>
#include <bootsource.h>
@@ -23,7 +7,7 @@
#include <init.h>
#include <linux/phy.h>
#include <linux/sizes.h>
-#include <mach/bbu.h>
+#include <mach/imx/bbu.h>
#include <envfs.h>
@@ -56,12 +40,10 @@ static int nxp_imx8mq_evk_init(void)
barebox_set_hostname("imx8mq-evk");
flags = bootsource_get_instance() == 0 ? BBU_HANDLER_FLAG_DEFAULT : 0;
- imx8mq_bbu_internal_mmc_register_handler("eMMC",
- "/dev/mmc0.barebox", flags);
+ imx8m_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc0", flags);
flags = bootsource_get_instance() == 1 ? BBU_HANDLER_FLAG_DEFAULT : 0;
- imx8mq_bbu_internal_mmc_register_handler("SD",
- "/dev/mmc1.barebox", flags);
+ imx8m_bbu_internal_mmc_register_handler("SD", "/dev/mmc1.barebox", flags);
if (bootsource_get_instance() == 0)
of_device_enable_path("/chosen/environment-emmc");
diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr.h b/arch/arm/boards/nxp-imx8mq-evk/ddr.h
index 65115dba1e..fd09ad6bf1 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/ddr.h
+++ b/arch/arm/boards/nxp-imx8mq-evk/ddr.h
@@ -8,7 +8,7 @@
*/
#include <common.h>
#include <io.h>
-#include <mach/imx8-ddrc.h>
+#include <soc/imx8m/ddr.h>
/*
* Code generated by i.MX8 M DDR Tool doesn't have any prefixes in the
@@ -20,10 +20,3 @@
void nxp_imx8mq_evk_ddr_init(void);
void nxp_imx8mq_evk_ddr_cfg_phy(void);
-
-#define FW_1D_IMAGE lpddr4_pmu_train_1d_imem_bin, \
- lpddr4_pmu_train_1d_dmem_bin
-#define FW_2D_IMAGE lpddr4_pmu_train_2d_imem_bin, \
- lpddr4_pmu_train_2d_dmem_bin
-
-
diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
index 39addea973..b1f752c4cb 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/ddr_init.c
@@ -81,6 +81,7 @@ void ddr_init(void)
reg32_write(0x3d400200,0x15);
reg32_write(0x3d40020c,0x0);
reg32_write(0x3d400210,0x1f1f);
+ reg32_write(0x3d40021c,0xf0f);
reg32_write(0x3d400204,0x80808);
reg32_write(0x3d400214,0x7070707);
reg32_write(0x3d400218,0x48080707);
@@ -222,4 +223,4 @@ void ddr_init(void)
/* enable DDR auto-refresh mode */
tmp = reg32_read(DDRC_RFSHCTL3(0)) & ~0x1;
reg32_write(DDRC_RFSHCTL3(0), tmp);
-} \ No newline at end of file
+}
diff --git a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
index 1b30ff7257..bac7d0a517 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/ddrphy_train.c
@@ -11,6 +11,8 @@
void ddr_cfg_phy(void) {
unsigned int tmp, tmp_t;
+ ddr_get_firmware(DRAM_TYPE_LPDDR4);
+
//Init DDRPHY register...
reg32_write(0x3c080440,0x2);
reg32_write(0x3c080444,0x3);
@@ -142,7 +144,7 @@ void ddr_cfg_phy(void) {
//enable APB bus to access DDRPHY RAM
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0);
//load the 1D training image
- ddr_load_train_code(FW_1D_IMAGE);
+ imx8m_ddr_load_train_code(DRAM_TYPE_LPDDR4, FW_1D_IMAGE);
//configure DDRPHY-FW DMEM structure @clock0...
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
@@ -187,7 +189,7 @@ void ddr_cfg_phy(void) {
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0);
- wait_ddrphy_training_complete();
+ imx8m_wait_ddrphy_training_complete();
//configure DDRPHY-FW DMEM structure @clock1...
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
@@ -256,7 +258,7 @@ void ddr_cfg_phy(void) {
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0);
- wait_ddrphy_training_complete();
+ imx8m_wait_ddrphy_training_complete();
//set the PHY input clock to the desired frequency for pstate 0
reg32_write(0x3038a088,0x7070000);
@@ -289,7 +291,7 @@ void ddr_cfg_phy(void) {
//enable APB bus to access DDRPHY RAM
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x0);
//load the 2D training image
- ddr_load_train_code(FW_2D_IMAGE);
+ imx8m_ddr_load_train_code(DRAM_TYPE_LPDDR4, FW_2D_IMAGE);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54003,0xc80);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x54006,0x11);
@@ -330,7 +332,7 @@ void ddr_cfg_phy(void) {
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x9);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x0);
- wait_ddrphy_training_complete();
+ imx8m_wait_ddrphy_training_complete();
//Halt MPU
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0099, 0x1);
@@ -932,4 +934,4 @@ void ddr_cfg_phy(void) {
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0x2006e, 0x0);
//disable APB bus to access DDRPHY RAM
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0000, 0x1);
-} \ No newline at end of file
+}
diff --git a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
index 11463fe850..f82759f849 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
+++ b/arch/arm/boards/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg
@@ -1,6 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
soc imx8mq
loadaddr 0x007E1000
max_load_size 0x3F000
-dcdofs 0x400
-#include <mach/habv4-imx8-gencsf.h>
+ivtofs 0x400
+
+#include <mach/imx/habv4-imx8-gencsf.h>
diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index 9d060fb589..d1a517dddb 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -1,91 +1,63 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
#include <common.h>
+#include <firmware.h>
#include <linux/sizes.h>
-#include <mach/generic.h>
+#include <mach/imx/generic.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
-#include <mach/imx8-ccm-regs.h>
-#include <mach/iomux-mx8.h>
-#include <mach/imx8-ddrc.h>
-#include <mach/xload.h>
+#include <mach/imx/imx8m-ccm-regs.h>
+#include <mach/imx/iomux-mx8mq.h>
+#include <soc/imx8m/ddr.h>
+#include <mach/imx/xload.h>
#include <io.h>
#include <debug_ll.h>
+#include <mach/imx/debug_ll.h>
#include <asm/cache.h>
#include <asm/sections.h>
#include <asm/mmu.h>
-#include <mach/atf.h>
-#include <mach/esdctl.h>
+#include <mach/imx/atf.h>
+#include <mach/imx/esdctl.h>
#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)
static void setup_uart(void)
{
- void __iomem *iomux = IOMEM(MX8MQ_IOMUXC_BASE_ADDR);
- void __iomem *ccm = IOMEM(MX8MQ_CCM_BASE_ADDR);
+ void __iomem *uart = IOMEM(MX8M_UART1_BASE_ADDR);
- writel(CCM_CCGR_SETTINGn_NEEDED(0),
- ccm + CCM_CCGRn_CLR(CCM_CCGR_UART1));
- writel(CCM_TARGET_ROOTn_ENABLE | UART1_CLK_ROOT__25M_REF_CLK,
- ccm + CCM_TARGET_ROOTn(UART1_CLK_ROOT));
- writel(CCM_CCGR_SETTINGn_NEEDED(0),
- ccm + CCM_CCGRn_SET(CCM_CCGR_UART1));
+ imx8m_early_setup_uart_clock();
- imx_setup_pad(iomux, IMX8MQ_PAD_UART1_TXD__UART1_TX | UART_PAD_CTRL);
+ imx8mq_setup_pad(IMX8MQ_PAD_UART1_TXD__UART1_TX | UART_PAD_CTRL);
+ imx8m_uart_setup(uart);
- imx8_uart_setup_ll();
+ pbl_set_putc(imx_uart_putc, uart);
putc_ll('>');
}
-static void nxp_imx8mq_evk_sram_setup(void)
-{
- ddr_init();
-}
-
/*
* Power-on execution flow of start_nxp_imx8mq_evk() might not be
* obvious for a very first read, so here's, hopefully helpful,
* summary:
*
* 1. MaskROM uploads PBL into OCRAM and that's where this function is
- * executed for the first time
- *
- * 2. DDR is initialized and the TF-A trampoline is installed in the
- * DRAM.
+ * executed for the first time. At entry the exception level is EL3.
*
- * 3. TF-A is executed and exits into the trampoline in RAM, which enters the
- * PBL for the second time. DRAM setup done is indicated by a one in register
- * x0 by the trampoline
+ * 2. DDR is initialized and the image is loaded from storage into DRAM. The PBL
+ * part is copied from OCRAM to the TF-A return address in DRAM.
*
- * 4. The piggydata is loaded from the SD card and copied to the expected
- * location in the DRAM.
+ * 3. TF-A is executed and exits into the PBL code in DRAM. TF-A has taken us
+ * from EL3 to EL2.
*
- * 5. Standard barebox boot flow continues
+ * 4. Standard barebox boot flow continues
*/
static __noreturn noinline void nxp_imx8mq_evk_start(void)
{
- enum bootsource src = BOOTSOURCE_UNKNOWN;
- int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
- int ret = -ENOTSUPP;
- const u8 *bl31;
- size_t bl31_size;
-
- if (IS_ENABLED(CONFIG_DEBUG_LL))
- setup_uart();
+ setup_uart();
/*
* If we are in EL3 we are running for the first time and need to
@@ -93,27 +65,15 @@ static __noreturn noinline void nxp_imx8mq_evk_start(void)
* to DRAM in EL2.
*/
if (current_el() == 3) {
- nxp_imx8mq_evk_sram_setup();
- get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
- /*
- * On completion the TF-A will jump to MX8MQ_ATF_BL33_BASE_ADDR in
- * EL2. Copy ourselves there.
- */
- memcpy((void *)MX8MQ_ATF_BL33_BASE_ADDR, _text, __bss_start - _text);
- imx8mq_atf_load_bl31(bl31, bl31_size);
- /* not reached */
- }
+ ddr_init();
- imx8_get_boot_source(&src, &instance);
+ imx8mq_load_and_start_image_via_tfa();
+ }
- if (src == BOOTSOURCE_MMC)
- ret = imx8_esdhc_load_piggy(instance);
- else
- BUG_ON(ret);
/*
* 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)