summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2022-09-06 08:59:51 -0400
committerTom Rini <[email protected]>2022-09-06 08:59:51 -0400
commit166d2693dd3447ffa18112611c85ee4bb37ffa4b (patch)
treeefa16cc06a6aa6f6b67cca5e635014b008aac60a /board
parent51601397fcbb13e6dc2e4223408230c82955a601 (diff)
parent44366be10a9386a8887124a77a7d06169c3aa1f3 (diff)
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
Diffstat (limited to 'board')
-rw-r--r--board/freescale/ls1043ardb/ddr.c2
-rw-r--r--board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c48
-rw-r--r--board/freescale/p1_p2_rdb_pc/spl.c6
-rw-r--r--board/freescale/p1_p2_rdb_pc/tlb.c2
-rw-r--r--board/kontron/sl28/common.c22
-rw-r--r--board/kontron/sl28/sl28.c43
-rw-r--r--board/kontron/sl28/sl28.h16
-rw-r--r--board/kontron/sl28/spl.c54
8 files changed, 189 insertions, 4 deletions
diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c
index 08b43ff5e4c..4d2fce38412 100644
--- a/board/freescale/ls1043ardb/ddr.c
+++ b/board/freescale/ls1043ardb/ddr.c
@@ -114,7 +114,7 @@ dimm_params_t ddr_raw_timing = {
.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 a71952dcf39..25906d3fc01 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,7 +83,19 @@ struct cpld_data {
#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_reset(void)
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 b60027ebd9a..eda84bf2b1f 100644
--- a/board/freescale/p1_p2_rdb_pc/spl.c
+++ b/board/freescale/p1_p2_rdb_pc/spl.c
@@ -31,6 +31,12 @@ void board_init_f(ulong bootflag)
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 105d9e38aac..65cedd42a0d 100644
--- a/board/freescale/p1_p2_rdb_pc/tlb.c
+++ b/board/freescale/p1_p2_rdb_pc/tlb.c
@@ -61,11 +61,11 @@ struct fsl_e_tlb_entry tlb_table[] = {
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 33c6843c3f7..331de29baee 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 @@ u32 get_lpuart_clk(void)
{
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 32e9694b77c..0576b3eae48 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 @@ int board_eth_init(struct bd_info *bis)
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 @@ static void stop_recovery_watchdog(void)
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 00000000000..7f0105049cb
--- /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 0e6ad5f37e1..ffaf517a8bb 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 @@ int board_fit_config_name_match(const char *name)
void board_boot_order(u32 *spl_boot_list)
{
- spl_boot_list[0] = BOOT_DEVICE_SPI;
+ 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)
+{
+ 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)