Merge tag 'fsl-qoriq-2022-9-6' of https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq

Reset fixes for p1_p2_rdb_pc
Fix use after free issue fix in fsl_enetc.c
Fix for fsl ddr: make bank_addr_bits reflect actual bits
sl28 board update
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
index 5f09ef0..3a4b665 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c
@@ -67,11 +67,24 @@
 #endif
 }
 
+void tzpc_init(void)
+{
+	/*
+	 * Mark the whole OCRAM as non-secure, otherwise DMA devices cannot
+	 * access it. This is for example necessary for MMC boot.
+	 */
+#ifdef TZPCR0SIZE_BASE
+	out_le32(TZPCR0SIZE_BASE, 0);
+#endif
+}
+
 void board_init_f(ulong dummy)
 {
 	int ret;
 
 	icache_enable();
+	tzpc_init();
+
 	/* Clear global data */
 	memset((void *)gd, 0, sizeof(gd_t));
 	if (IS_ENABLED(CONFIG_DEBUG_UART))
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index 1b6cdc4..14d5c56 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -44,7 +44,9 @@
 {
 	/* Do nothing */
 }
+void board_reset_prepare(void) __attribute__((weak, alias("__board_reset")));
 void board_reset(void) __attribute__((weak, alias("__board_reset")));
+void board_reset_last(void) __attribute__((weak, alias("__board_reset")));
 
 int checkcpu (void)
 {
@@ -319,12 +321,18 @@
 #else
 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 
+	/* Call board-specific preparation for reset */
+	board_reset_prepare();
+
 	/* Attempt board-specific reset */
 	board_reset();
 
 	/* Next try asserting HRESET_REQ */
 	out_be32(&gur->rstcr, 0x2);
 	udelay(100);
+
+	/* Attempt last-stage board-specific reset */
+	board_reset_last();
 #endif
 
 	return 1;
diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c
index 08b43ff..4d2fce3 100644
--- a/board/freescale/ls1043ardb/ddr.c
+++ b/board/freescale/ls1043ardb/ddr.c
@@ -114,7 +114,7 @@
 	.mirrored_dimm = 0,
 	.n_row_addr = 15,
 	.n_col_addr = 10,
-	.bank_addr_bits = 0,
+	.bank_addr_bits = 2,
 	.bank_group_bits = 2,
 	.edc_config = 0,
 	.burst_lengths_bitmask = 0x0c,
diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
index a71952d..25906d3 100644
--- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
+++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
@@ -83,8 +83,20 @@
 #define CPLD_FXS_LED	0x0F
 #define CPLD_SYS_RST	0x00
 
-void board_reset(void)
+void board_reset_prepare(void)
 {
+	/*
+	 * During reset preparation, turn off external watchdog.
+	 * This ensures that external watchdog does not trigger
+	 * another reset or possible infinite reset loop.
+	 */
+	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
+	out_8(&cpld_data->wd_cfg, CPLD_WD_CFG);
+	in_8(&cpld_data->wd_cfg); /* Read back to sync write */
+}
+
+void board_reset_last(void)
+{
 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
 	out_8(&cpld_data->system_rst, 1);
 }
@@ -92,12 +104,46 @@
 void board_cpld_init(void)
 {
 	struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
+	u8 prev_wd_cfg = in_8(&cpld_data->wd_cfg);
 
 	out_8(&cpld_data->wd_cfg, CPLD_WD_CFG);
 	out_8(&cpld_data->status_led, CPLD_STATUS_LED);
 	out_8(&cpld_data->fxo_led, CPLD_FXO_LED);
 	out_8(&cpld_data->fxs_led, CPLD_FXS_LED);
+
+	/*
+	 * CPLD's system reset register on P1/P2 RDB boards is not autocleared
+	 * after flipping it. If this register is set to one then CPLD triggers
+	 * reset of CPU in few ms.
+	 *
+	 * CPLD does not trigger reset of CPU for 100ms after the last reset.
+	 *
+	 * This means that trying to reset board via CPLD system reset register
+	 * cause reboot loop. To prevent this reboot loop, the only workaround
+	 * is to try to clear CPLD's system reset register as early as possible
+	 * and it has to be done in 100ms since the last start of reset.
+	 */
 	out_8(&cpld_data->system_rst, CPLD_SYS_RST);
+
+	/*
+	 * If watchdog timer was already set to non-disabled value then it means
+	 * that watchdog timer was already activated, has already expired and
+	 * caused CPU reset. If this happened then due to CPLD firmware bug,
+	 * writing to wd_cfg register has no effect and therefore it is not
+	 * possible to reactivate watchdog timer again. Also if CPU was reset
+	 * via watchdog then some peripherals like i2c do not work. Watchdog and
+	 * i2c start working again after CPU reset via non-watchdog method.
+	 *
+	 * So in case watchdog timer register in CPLD was already enabled then
+	 * disable it in CPLD and reset CPU which cause new boot. Watchdog timer
+	 * is disabled few lines above, after reading CPLD previous value.
+	 * This logic (disabling timer before reset) prevents reboot loop.
+	 */
+	if (prev_wd_cfg != CPLD_WD_CFG) {
+		eieio();
+		do_reset(NULL, 0, 0, NULL);
+		while (1); /* do_reset() does not occur immediately */
+	}
 }
 
 void board_gpio_init(void)
diff --git a/board/freescale/p1_p2_rdb_pc/spl.c b/board/freescale/p1_p2_rdb_pc/spl.c
index b60027e..eda84bf 100644
--- a/board/freescale/p1_p2_rdb_pc/spl.c
+++ b/board/freescale/p1_p2_rdb_pc/spl.c
@@ -31,6 +31,12 @@
 	u32 plat_ratio, bus_clk;
 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
 
+	/*
+	 * Call board_early_init_f() as early as possible as it workarounds
+	 * reboot loop due to broken CPLD state machine for reset line.
+	 */
+	board_early_init_f();
+
 	console_init_f();
 
 	/* Set pmuxcr to allow both i2c1 and i2c2 */
diff --git a/board/freescale/p1_p2_rdb_pc/tlb.c b/board/freescale/p1_p2_rdb_pc/tlb.c
index 105d9e3..65cedd4 100644
--- a/board/freescale/p1_p2_rdb_pc/tlb.c
+++ b/board/freescale/p1_p2_rdb_pc/tlb.c
@@ -61,11 +61,11 @@
 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 			0, 5, BOOKE_PAGESZ_1M, 1),
 #endif
+#endif /* not SPL */
 
 	SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS,
 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 			0, 6, BOOKE_PAGESZ_1M, 1),
-#endif /* not SPL */
 
 #ifdef CONFIG_SYS_NAND_BASE
 	/* *I*G - NAND */
diff --git a/board/kontron/sl28/common.c b/board/kontron/sl28/common.c
index 33c6843..331de29 100644
--- a/board/kontron/sl28/common.c
+++ b/board/kontron/sl28/common.c
@@ -2,6 +2,9 @@
 
 #include <common.h>
 #include <asm/global_data.h>
+#include <asm/io.h>
+
+#include "sl28.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -9,3 +12,22 @@
 {
 	return gd->bus_clk / CONFIG_SYS_FSL_LPUART_CLK_DIV;
 }
+
+enum boot_source sl28_boot_source(void)
+{
+	u32 rcw_src = in_le32(DCFG_BASE + DCFG_PORSR1) & DCFG_PORSR1_RCW_SRC;
+
+	switch (rcw_src) {
+	case DCFG_PORSR1_RCW_SRC_SDHC1:
+		return BOOT_SOURCE_SDHC;
+	case DCFG_PORSR1_RCW_SRC_SDHC2:
+		return BOOT_SOURCE_MMC;
+	case DCFG_PORSR1_RCW_SRC_I2C:
+		return BOOT_SOURCE_I2C;
+	case DCFG_PORSR1_RCW_SRC_FSPI_NOR:
+		return BOOT_SOURCE_SPI;
+	default:
+		debug("unknown bootsource (%08x)\n", rcw_src);
+		return BOOT_SOURCE_UNKNOWN;
+	}
+}
diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c
index 32e9694..0576b3e 100644
--- a/board/kontron/sl28/sl28.c
+++ b/board/kontron/sl28/sl28.c
@@ -24,6 +24,8 @@
 #include <fdtdec.h>
 #include <miiphy.h>
 
+#include "sl28.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT)
@@ -60,6 +62,27 @@
 	return pci_eth_init(bis);
 }
 
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+	enum boot_source src = sl28_boot_source();
+
+	if (prio)
+		return ENVL_UNKNOWN;
+
+	if (!CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
+		return ENVL_NOWHERE;
+
+	/* write and erase always operate on the environment */
+	if (op == ENVOP_SAVE || op == ENVOP_ERASE)
+		return ENVL_SPI_FLASH;
+
+	/* failsafe boot will always use the compiled-in default environment */
+	if (src == BOOT_SOURCE_SPI)
+		return ENVL_NOWHERE;
+
+	return ENVL_SPI_FLASH;
+}
+
 static int __sl28cpld_read(uint reg)
 {
 	struct udevice *dev;
@@ -103,8 +126,28 @@
 		wdt_stop(dev);
 }
 
+static void sl28_set_prompt(void)
+{
+	enum boot_source src = sl28_boot_source();
+
+	switch (src) {
+	case BOOT_SOURCE_SPI:
+		env_set("PS1", "[FAILSAFE] => ");
+		break;
+	case BOOT_SOURCE_SDHC:
+		env_set("PS1", "[SDHC] => ");
+		break;
+	default:
+		env_set("PS1", NULL);
+		break;
+	}
+}
+
 int fsl_board_late_init(void)
 {
+	if (IS_ENABLED(CONFIG_CMDLINE_PS_SUPPORT))
+		sl28_set_prompt();
+
 	/*
 	 * Usually, the after a board reset, the watchdog is enabled by
 	 * default. This is to supervise the bootloader boot-up. Therefore,
diff --git a/board/kontron/sl28/sl28.h b/board/kontron/sl28/sl28.h
new file mode 100644
index 0000000..7f01050
--- /dev/null
+++ b/board/kontron/sl28/sl28.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __SL28_H
+#define __SL28_H
+
+enum boot_source {
+	BOOT_SOURCE_UNKNOWN,
+	BOOT_SOURCE_SDHC,
+	BOOT_SOURCE_MMC,
+	BOOT_SOURCE_I2C,
+	BOOT_SOURCE_SPI,
+};
+
+enum boot_source sl28_boot_source(void);
+
+#endif
diff --git a/board/kontron/sl28/spl.c b/board/kontron/sl28/spl.c
index 0e6ad5f..ffaf517 100644
--- a/board/kontron/sl28/spl.c
+++ b/board/kontron/sl28/spl.c
@@ -5,6 +5,9 @@
 #include <asm/spl.h>
 #include <asm/arch-fsl-layerscape/fsl_serdes.h>
 #include <asm/arch-fsl-layerscape/soc.h>
+#include <spi_flash.h>
+
+#include "sl28.h"
 
 #define DCFG_RCWSR25 0x160
 #define GPINFO_HW_VARIANT_MASK 0xff
@@ -58,7 +61,56 @@
 
 void board_boot_order(u32 *spl_boot_list)
 {
+	enum boot_source src = sl28_boot_source();
+
+	switch (src) {
+	case BOOT_SOURCE_SDHC:
+		spl_boot_list[0] = BOOT_DEVICE_MMC2;
+		break;
+	case BOOT_SOURCE_SPI:
+	case BOOT_SOURCE_I2C:
+		spl_boot_list[0] = BOOT_DEVICE_SPI;
+		break;
+	case BOOT_SOURCE_MMC:
+		spl_boot_list[0] = BOOT_DEVICE_MMC1;
+		break;
+	default:
+		panic("unexpected bootsource (%d)\n", src);
+		break;
+	}
+}
+
+unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash)
+{
+	enum boot_source src = sl28_boot_source();
+
+	switch (src) {
+	case BOOT_SOURCE_SPI:
+		return 0x000000;
+	case BOOT_SOURCE_I2C:
+		return 0x230000;
+	default:
+		panic("unexpected bootsource (%d)\n", src);
+		break;
+	}
+}
+
+const char *spl_board_loader_name(u32 boot_device)
+{
-	spl_boot_list[0] = BOOT_DEVICE_SPI;
+	enum boot_source src = sl28_boot_source();
+
+	switch (src) {
+	case BOOT_SOURCE_SDHC:
+		return "SD card (Test mode)";
+	case BOOT_SOURCE_SPI:
+		return "Failsafe SPI flash";
+	case BOOT_SOURCE_I2C:
+		return "SPI flash";
+	case BOOT_SOURCE_MMC:
+		return "eMMC";
+	default:
+		return "(unknown)";
+	}
 }
 
 int board_early_init_f(void)
diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig
index b0b5fb1..fc1c607 100644
--- a/configs/kontron_sl28_defconfig
+++ b/configs/kontron_sl28_defconfig
@@ -12,6 +12,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1028a-kontron-sl28"
 CONFIG_SPL_TEXT_BASE=0x18010000
 CONFIG_SYS_FSL_SDHC_CLK_DIV=1
+CONFIG_SPL_MMC=y
 CONFIG_SPL_SERIAL=y
 CONFIG_SPL_SIZE_LIMIT=0x20000
 CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0
@@ -46,12 +47,15 @@
 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
 CONFIG_SPL_STACK=0x18009ff0
 CONFIG_SYS_SPL_MALLOC=y
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x900
 CONFIG_SPL_MPC8XXX_INIT_DDR=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x230000
 CONFIG_SYS_CBSIZE=256
 CONFIG_SYS_PBSIZE=276
 CONFIG_SYS_BOOTM_LEN=0x800000
+CONFIG_CMDLINE_PS_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_GREPENV=y
 CONFIG_CMD_NVEDIT_EFI=y
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index b5122d1..0b0b4e5 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -214,7 +214,7 @@
 		odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
 		odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
 #ifdef CONFIG_SYS_FSL_DDR4
-		ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits;
+		ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits - 2;
 		bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits;
 #else
 		n_banks_per_sdram_device
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index e2bdc12..ea79162 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -246,7 +246,7 @@
 	/* SDRAM device parameters */
 	pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12;
 	pdimm->n_col_addr = (spd->addressing & 0x7) + 9;
-	pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3;
+	pdimm->bank_addr_bits = ((spd->density_banks >> 4) & 0x3) + 2;
 	pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3;
 
 	/*
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 2f76beb..eb2f06e 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -27,9 +27,9 @@
 /* Option parameter Structures */
 struct options_string {
 	const char *option_name;
-	size_t offset;
-	unsigned int size;
-	const char printhex;
+	u32 offset : 9;
+	u32 size : 4;
+	u32 printhex : 1;
 };
 
 static unsigned int picos_to_mhz(unsigned int picos)
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
index cd4c2c2..835e5bd 100644
--- a/drivers/net/fsl_enetc.c
+++ b/drivers/net/fsl_enetc.c
@@ -22,6 +22,8 @@
 
 #define ENETC_DRIVER_NAME	"enetc_eth"
 
+static int enetc_remove(struct udevice *dev);
+
 /*
  * sets the MAC address in IERB registers, this setting is persistent and
  * carried over to Linux.
@@ -319,6 +321,7 @@
 static int enetc_probe(struct udevice *dev)
 {
 	struct enetc_priv *priv = dev_get_priv(dev);
+	int res;
 
 	if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) {
 		enetc_dbg(dev, "interface disabled\n");
@@ -350,7 +353,10 @@
 
 	enetc_start_pcs(dev);
 
-	return enetc_config_phy(dev);
+	res = enetc_config_phy(dev);
+	if(res)
+		enetc_remove(dev);
+	return res;
 }
 
 /*
diff --git a/include/configs/kontron_sl28.h b/include/configs/kontron_sl28.h
index 38063ba..df46e58 100644
--- a/include/configs/kontron_sl28.h
+++ b/include/configs/kontron_sl28.h
@@ -37,8 +37,6 @@
 /* serial port */
 #define CONFIG_SYS_NS16550_CLK          (get_bus_freq(0) / 2)
 
-#define COUNTER_FREQUENCY_REAL		(get_board_sys_clk() / 4)
-
 /* SPL */
 
 #define CONFIG_SYS_MONITOR_LEN		(1024 * 1024)