Subject: [PATCH 2/2] ARM: Layerscape: Add LS1021A IOT board support
Renaud Barbier
Renaud.Barbier at ametek.com
Thu Feb 23 05:58:46 PST 2023
The LS1021A-IOT is a NXP reference board.
Currently supported:
- DDR3 RAM fixed settings
- UART
- SPI boot
Signed-off-by: Renaud Barbier <renaud.barbier at ametek.com>
---
arch/arm/boards/Makefile | 1 +
arch/arm/boards/ls1021aiot/Makefile | 3 +
arch/arm/boards/ls1021aiot/board.c | 47 +++++++
arch/arm/boards/ls1021aiot/lowlevel.c | 120 ++++++++++++++++++
arch/arm/boards/ls1021aiot/ls102xa_pbi.cfg | 11 ++
.../boards/ls1021aiot/ls102xa_rcw_sd_qspi.cfg | 8 ++
arch/arm/boards/ls1021aiot/start.S | 11 ++
arch/arm/configs/layerscape_v7_defconfig | 94 ++++++++++++++
arch/arm/dts/Makefile | 1 +
arch/arm/dts/fsl-ls1021a-iot.dts | 77 +++++++++++
arch/arm/lib32/Makefile | 1 +
arch/arm/lib32/pbl.c | 21 +++
12 files changed, 395 insertions(+)
create mode 100644 arch/arm/boards/ls1021aiot/Makefile
create mode 100644 arch/arm/boards/ls1021aiot/board.c
create mode 100644 arch/arm/boards/ls1021aiot/lowlevel.c
create mode 100644 arch/arm/boards/ls1021aiot/ls102xa_pbi.cfg
create mode 100644 arch/arm/boards/ls1021aiot/ls102xa_rcw_sd_qspi.cfg
create mode 100644 arch/arm/boards/ls1021aiot/start.S
create mode 100644 arch/arm/configs/layerscape_v7_defconfig
create mode 100644 arch/arm/dts/fsl-ls1021a-iot.dts
create mode 100644 arch/arm/lib32/pbl.c
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index f47aea6602..b148c8c1c1 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -192,6 +192,7 @@ obj-$(CONFIG_MACH_ZII_IMX7D_DEV) += zii-imx7d-dev/
obj-$(CONFIG_MACH_WAGO_PFC_AM35XX) += wago-pfc-am35xx/
obj-$(CONFIG_MACH_LS1046ARDB) += ls1046ardb/
obj-$(CONFIG_MACH_TQMLS1046A) += tqmls1046a/
+obj-$(CONFIG_MACH_LS1021AIOT) += ls1021aiot/
obj-$(CONFIG_MACH_MNT_REFORM) += mnt-reform/
obj-$(CONFIG_MACH_SKOV_ARM9CPU) += skov-arm9cpu/
obj-$(CONFIG_MACH_RK3568_EVB) += rockchip-rk3568-evb/
diff --git a/arch/arm/boards/ls1021aiot/Makefile b/arch/arm/boards/ls1021aiot/Makefile
new file mode 100644
index 0000000000..df69ce814b
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/Makefile
@@ -0,0 +1,3 @@
+lwl-y += lowlevel.o
+obj-y += board.o
+lwl-y += start.o
diff --git a/arch/arm/boards/ls1021aiot/board.c b/arch/arm/boards/ls1021aiot/board.c
new file mode 100644
index 0000000000..6fe35f008c
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/board.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+// SPDX-FileCopyrightText: (C) Copyright 2023 Ametek Inc.
+// SPDX-FileCopyrightText: 2023 Renaud Barbier <renaud.barbier at ametek.com>,
+
+#include <common.h>
+#include <init.h>
+#include <bbu.h>
+#include <net.h>
+#include <crc.h>
+#include <fs.h>
+#include <io.h>
+#include <envfs.h>
+#include <libfile.h>
+#include <asm/memory.h>
+#include <linux/sizes.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <asm/system.h>
+#include <mach/layerscape.h>
+#include <of_address.h>
+#include <soc/fsl/immap_lsch2.h>
+
+static int iot_mem_init(void)
+{
+ if (!of_machine_is_compatible("fsl,ls1021a"))
+ return 0;
+
+ arm_add_mem_device("ram0", 0x80000000, 0x40000000);
+
+ return 0;
+}
+mem_initcall(iot_mem_init);
+
+static int iot_postcore_init(void)
+{
+ struct ls102xa_ccsr_scfg *scfg = IOMEM(LSCH2_SCFG_ADDR);
+
+ if (!of_machine_is_compatible("fsl,ls1021a"))
+ return 0;
+
+ /* clear BD & FR bits for BE BD's and frame data */
+ clrbits_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
+ out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125);
+
+ return 0;
+}
+coredevice_initcall(iot_postcore_init);
diff --git a/arch/arm/boards/ls1021aiot/lowlevel.c b/arch/arm/boards/ls1021aiot/lowlevel.c
new file mode 100644
index 0000000000..210f4433b6
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/lowlevel.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+// SPDX-FileCopyrightText: (C) Copyright 2023 Ametek Inc.
+// SPDX-FileCopyrightText: 2023 Renaud Barbier <renaud.barbier at ametek.com>
+
+/*
+ * Derived from Freescale LSDK-19.09-update-311219
+ */
+#include <common.h>
+#include <clock.h>
+#include <debug_ll.h>
+#include <image-metadata.h>
+#include <soc/fsl/fsl_ddr_sdram.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <asm/syscounter.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/sizes.h>
+#include <mach/errata.h>
+#include <mach/lowlevel.h>
+#include <mach/xload.h>
+#include <mach/layerscape.h>
+
+static struct fsl_ddr_controller ddrc[] = {
+ {
+ .memctl_opts.ddrtype = SDRAM_TYPE_DDR3,
+ .base = IOMEM(LSCH2_DDR_ADDR),
+ .ddr_freq = LS1021A_DDR_FREQ,
+ .erratum_A009942 = 1,
+ .chip_selects_per_ctrl = 4,
+ .fsl_ddr_config_reg = {
+ .cs[0].bnds = 0x008000bf,
+ .cs[0].config = 0x80014302,
+ .cs[0].config_2 = 0x00000000,
+ .cs[1].bnds = 0x00000000,
+ .cs[1].config = 0x00000000,
+ .cs[1].config_2 = 0x00000000,
+ .cs[2].bnds = 0x00000000,
+ .cs[2].config = 0x00000000,
+ .cs[2].config_2 = 0x00000000,
+ .cs[3].bnds = 0x00000000,
+ .cs[3].config = 0x00000000,
+ .cs[3].config_2 = 0x00000000,
+ .timing_cfg_3 = 0x010e1000,
+ .timing_cfg_0 = 0x50550004,
+ .timing_cfg_1 = 0xbcb38c56,
+ .timing_cfg_2 = 0x0040d120,
+ .ddr_sdram_cfg = 0x470c0008,
+ .ddr_sdram_cfg_2 = 0x00401010,
+ .ddr_sdram_mode = 0x00061c60,
+ .ddr_sdram_mode_2 = 0x00180000,
+ .ddr_sdram_interval = 0x18600618,
+ .ddr_data_init = 0xDEADBEEF,
+ .ddr_sdram_clk_cntl = 0x02000000,
+ .ddr_init_addr = 0x00000000,
+ .ddr_init_ext_addr = 0x00000000,
+ .timing_cfg_4 = 0x00000001,
+ .timing_cfg_5 = 0x03401400,
+ .ddr_zq_cntl = 0x89080600,
+ .ddr_wrlvl_cntl = 0x8655f605,
+ .ddr_wrlvl_cntl_2 = 0x05060607,
+ .ddr_wrlvl_cntl_3 = 0x05050505,
+ .ddr_sr_cntr = 0x00000000,
+ .ddr_sdram_rcw_1 = 0x00000000,
+ .ddr_sdram_rcw_2 = 0x00000000,
+ .ddr_sdram_rcw_3 = 0x00000000,
+ .ddr_cdr1 = 0x80040000,
+ .ddr_cdr2 = 0x000000C0,
+ .dq_map_0 = 0x00000000,
+ .dq_map_1 = 0x00000000,
+ .dq_map_2 = 0x00000000,
+ .dq_map_3 = 0x00000000,
+ .debug[28] = 0x00700046,
+ },
+ },
+};
+
+extern char __dtb_fsl_ls1021a_iot_start[];
+
+static noinline __noreturn void ls1021aiot_r_entry(void)
+{
+ unsigned long membase = LAYERSCAPE_DDR_SDRAM_BASE;
+
+ if (get_pc() >= membase) {
+ barebox_arm_entry(membase, SZ_1G - SZ_64M,
+ __dtb_fsl_ls1021a_iot_start);
+ }
+
+ arm_cpu_lowlevel_init();
+ ls102xa_init_lowlevel();
+
+ debug_ll_init();
+
+ udelay(500);
+ putc_ll('>');
+
+ IMD_USED_OF(fsl_ls1021a_iot);
+
+ fsl_ddr_set_memctl_regs(&ddrc[0], 0);
+
+ layerscape_errata_post_ddr();
+
+ layerscape_xload_start_image(SZ_1G, 0, 0);
+
+ pr_err("Booting failed\n");
+
+ while (1)
+ ;
+}
+
+void ls1021aiot_entry(unsigned long r0, unsigned long r1, unsigned long r2);
+
+__noreturn void
+ls1021aiot_entry(unsigned long r0, unsigned long r1, unsigned long r2)
+{
+ relocate_to_current_adr();
+ setup_c();
+
+ ls1021aiot_r_entry();
+}
diff --git a/arch/arm/boards/ls1021aiot/ls102xa_pbi.cfg b/arch/arm/boards/ls1021aiot/ls102xa_pbi.cfg
new file mode 100644
index 0000000000..840299be8d
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/ls102xa_pbi.cfg
@@ -0,0 +1,11 @@
+#PBI commands
+
+09570200 ffffffff
+09570158 00000300
+8940007c 21f47300
+#Configure Scratch register
+09ee0200 10000000
+#Configure alternate space
+09570158 00001000
+#Flush PBL data
+096100c0 000FFFFF
diff --git a/arch/arm/boards/ls1021aiot/ls102xa_rcw_sd_qspi.cfg b/arch/arm/boards/ls1021aiot/ls102xa_rcw_sd_qspi.cfg
new file mode 100644
index 0000000000..3b5300501d
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/ls102xa_rcw_sd_qspi.cfg
@@ -0,0 +1,8 @@
+#PBL preamble and RCW header
+aa55aa55 01ee0100
+
+#disable IFC, enable QSPI and DSPI
+0608000a 00000000 00000000 00000000
+20000000 08407900 e0025a00 21046000
+00000000 00000000 00000000 20038000
+20024800 881b1340 00000000 00000000
diff --git a/arch/arm/boards/ls1021aiot/start.S b/arch/arm/boards/ls1021aiot/start.S
new file mode 100644
index 0000000000..c907777ca1
--- /dev/null
+++ b/arch/arm/boards/ls1021aiot/start.S
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <linux/linkage.h>
+#include <asm/barebox-arm64.h>
+
+#define STACK_TOP 0x10020000
+
+ENTRY_PROC(start_ls1021aiot)
+ ldr r3, =STACK_TOP
+ mov sp, r3
+ b ls1021aiot_entry
+ENTRY_PROC_END(start_ls1021aiot)
diff --git a/arch/arm/configs/layerscape_v7_defconfig b/arch/arm/configs/layerscape_v7_defconfig
new file mode 100644
index 0000000000..69176738d7
--- /dev/null
+++ b/arch/arm/configs/layerscape_v7_defconfig
@@ -0,0 +1,94 @@
+CONFIG_ARCH_LAYERSCAPE=y
+CONFIG_MACH_LS1021AIOT=y
+CONFIG_MMU=y
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_RELOCATABLE=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_BOOTM_SHOW_TYPE=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BOOTM_OFTREE=y
+CONFIG_BOOTM_OFTREE_UIMAGE=y
+CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ACTIVATE_NONE=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_RESET_SOURCE=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBIFORMAT=y
+CONFIG_CMD_UMOUNT=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_MENUTREE=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_LED_TRIGGER=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_SPI_FSL_QUADSPI=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_I2C=y
+CONFIG_I2C_IMX=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_MCI=y
+CONFIG_MCI_MMC_BOOT_PARTITIONS=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_LED_PCA955X=y
+CONFIG_EEPROM_AT25=y
+CONFIG_EEPROM_AT24=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_ZLIB=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_FS_TFTP=y
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index dca13df4ba..f3dd88241b 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -200,6 +200,7 @@ lwl-$(CONFIG_MACH_ZII_IMX7D_DEV) += imx7d-zii-rpu2.dtb.o imx7d-zii-rmu2.dtb.o
lwl-$(CONFIG_MACH_WAGO_PFC_AM35XX) += am35xx-pfc-750_820x.dtb.o
lwl-$(CONFIG_MACH_LS1046ARDB) += fsl-ls1046a-rdb.dtb.o
lwl-$(CONFIG_MACH_TQMLS1046A) += fsl-tqmls1046a-mbls10xxa.dtb.o
+lwl-$(CONFIG_MACH_LS1021AIOT) += fsl-ls1021a-iot.dtb.o
lwl-$(CONFIG_MACH_ZEDBOARD) += zynq-zed.dtb.o
lwl-$(CONFIG_MACH_MNT_REFORM) += imx8mq-mnt-reform2.dtb.o
diff --git a/arch/arm/dts/fsl-ls1021a-iot.dts b/arch/arm/dts/fsl-ls1021a-iot.dts
new file mode 100644
index 0000000000..85331eefb4
--- /dev/null
+++ b/arch/arm/dts/fsl-ls1021a-iot.dts
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Freescale ls1021a IOT board device tree source
+ *
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ */
+
+/dts-v1/;
+
+#include <arm/ls1021a-iot.dts>
+
+/ {
+ chosen {
+ stdout-path = &uart0;
+
+ environment {
+ compatible = "barebox,environment";
+ device-path = &environment_qspi;
+ };
+ };
+};
+
+&qspi {
+ bus-num = <0>;
+ status = "okay";
+
+ s70fl01gs: flash at 0 {
+ compatible = "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+
+ partitions {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "fixed-partitions";
+
+ partition at 0 {
+ label = "barebox";
+ reg = <0 0x100000>;
+ };
+
+ environment_qspi: partition at 100000 {
+ label = "barebox-environment";
+ reg = <0x100000 0x40000>;
+ };
+ };
+ };
+};
+
+&i2c0 {
+ status = "disabled";
+};
+
+&i2c1 {
+ status = "okay";
+ eeprom at 51 {
+ compatible = "atmel,24c512";
+ reg = <0x51>;
+ };
+};
+
+/* I2C1 and I2C2 are connected due to Errata on rev1 board */
+&i2c2 {
+ status = "disabled";
+};
+
+&uart0 {
+ status = "okay";
+ clock-frequency = <150000000>;
+};
+
+&uart1 {
+ status = "disabled";
+};
diff --git a/arch/arm/lib32/Makefile b/arch/arm/lib32/Makefile
index 82507fffc0..1be8d70c45 100644
--- a/arch/arm/lib32/Makefile
+++ b/arch/arm/lib32/Makefile
@@ -31,6 +31,7 @@ extra-y += barebox.lds
pbl-y += lib1funcs.o
pbl-y += ashldi3.o
pbl-y += div0.o
+pbl-y += pbl.o
obj-pbl-y += setjmp.o
diff --git a/arch/arm/lib32/pbl.c b/arch/arm/lib32/pbl.c
new file mode 100644
index 0000000000..f4be7b57dc
--- /dev/null
+++ b/arch/arm/lib32/pbl.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <asm/system.h>
+#include <clock.h>
+#include <common.h>
+
+void udelay(unsigned long us)
+{
+ unsigned long long ticks, cntfrq = get_cntfrq();
+ unsigned long long start = get_cntpct();
+
+ ticks = us * cntfrq + 999999;
+ do_div(ticks, 1000000);
+
+ while ((long)(start + ticks - get_cntpct()) > 0);
+}
+
+void mdelay(unsigned long ms)
+{
+ udelay(ms * 1000);
+}
--
2.27.0
More information about the barebox
mailing list