Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add temporary workaround for the reboot issues #564

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Li Hua Qian <[email protected]>
Date: Thu, 17 Oct 2024 11:31:38 +0800
Subject: [PATCH] qspi: iot2050: Add temporary workaround for the QSPI issue

After approximately 2 months of operation, the device may fail to check
the QSPI idle status. Here is the strange phenomenon: The QSPI remains
busy when checking the idle status, becoming idle once stop checking.
This commit provides a temporary workaround to bypass the QSPI idle
checking.

TODO: Implement a permanent solution for QSPI idle checking issue.

Signed-off-by: Li Hua Qian <[email protected]>
---
drivers/spi/cadence_qspi_apb.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 9ce2c0f254f3..2c32c4fc6b10 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -173,7 +173,20 @@ static unsigned int cadence_qspi_wait_idle(void *reg_base)
/* Timeout, still in busy mode. */
printf("QSPI: QSPI is still busy after poll for %d times.\n",
CQSPI_REG_RETRY);
- return 0;
+
+ /*
+ * TODO: Implement a permanent solution for QSPI idle checking issue.
+ * After approximately 2 months of operation, the device may fail to check
+ * the QSPI idle status. Here is the strange phenomenon: The QSPI remains
+ * busy when checking the idle status, becoming idle once stop checking.
+ * Providing a temporary workaround to bypass the QSPI idle checking.
+ */
+ if (CQSPI_REG_IS_IDLE(reg_base)) {
+ printf("QSPI: Idle state is %d, continue boot.\n",
+ CQSPI_REG_IS_IDLE(reg_base));
+ }
+
+ return 1;
}

void cadence_qspi_apb_readdata_capture(void *reg_base,
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Li Hua Qian <[email protected]>
Date: Wed, 16 Oct 2024 17:03:10 +0800
Subject: [PATCH] board: iot2050: Reset the eMMC when it isn't reachable

After approximately 2 months of operation, the device may fail to detect
the eMMC when rebooting. This commit provides a temporary workaround to
reset the eMMC if detection issues occur.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this issue likely related to how the board is wiring the eMMC, or is this a generic problem that should be addressed at eMMC driver level in U-Boot?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"For backward compatibility reason, RST_n signal is temporary disabled in device by default." - eMMC standard.

Therefore, this feature is not mandatory. If the workaround proves effective, we'll consider incorporating it into the eMMC driver.

TODO: Implement a permanent solution for eMMC detection issues.

Signed-off-by: Li Hua Qian <[email protected]>
---
board/siemens/iot2050/board.c | 61 +++++++++++++++++++++++++++++++
board/siemens/iot2050/iot2050.env | 9 +++++
configs/iot2050_defconfig | 3 +-
3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/board/siemens/iot2050/board.c b/board/siemens/iot2050/board.c
index 8497212ab890..f9b7f4d344d3 100644
--- a/board/siemens/iot2050/board.c
+++ b/board/siemens/iot2050/board.c
@@ -464,8 +464,69 @@ static bool user_button_pressed(void)

#define SERDES0_LANE_SELECT 0x00104080

+static int reset_emmc(void)
+{
+ const char *gpio_name = "gpio@601000_14";
+ struct gpio_desc gpio;
+ int ret;
+
+ ret = dm_gpio_lookup_name(gpio_name, &gpio);
+ if (ret < 0) {
+ pr_err("dm_gpio_lookup_name failed for %s: %d\n", gpio_name, ret);
+ return -1;
+ }
+
+ ret = dm_gpio_request(&gpio, "RESET_EMMC");
+ if (ret < 0) {
+ pr_err("dm_gpio_request failed for %s: %d\n", gpio_name, ret);
+ return -1;
+ }
+
+ ret = dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
+ if (ret < 0) {
+ pr_err("dm_gpio_set_dir_flags failed for %s: %d\n", gpio_name, ret);
+ return -1;
+ }
+
+ dm_gpio_set_value(&gpio, 0);
+ mdelay(4 * 100);
+ dm_gpio_set_value(&gpio, 1);
+
+ return 0;
+}
+
int board_late_init(void)
{
+ /*
+ * TODO: Implement a permanent solution for eMMC detection issues.
+ * After approximately 2 months of operation, the device may fail to
+ * detect the eMMC when rebooting. This following code snippet pulls the
+ * reset pin of eMMC, providing a temporary workaround to reset the eMMC
+ * if detection issues occur.
+ */
+ struct mmc *mmc;
+ int mmc_available = 0;
+
+ if (board_is_advanced()) {
+ for (int i = 0; i < 2; i++) {
+ mmc = find_mmc_device(i);
+ if (mmc && !mmc_init(mmc)) {
+ mmc_available = 1;
+ printf("%s-[%d]: mmc %d is available!\n",
+ __func__, __LINE__, i);
+ break;
+ }
+ }
+
+ if (!mmc_available) {
+ printf("%s-[%d]: eMMC wasn't found, reset eMMC ...\n",
+ __func__, __LINE__);
+ if(reset_emmc())
+ pr_err("%s [%d]: Failed to reset eMMC ...\n",
+ __func__, __LINE__);
+ }
+ }
+
/* change CTRL_MMR register to let serdes0 not output USB3.0 signals. */
writel(0x3, SERDES0_LANE_SELECT);

diff --git a/board/siemens/iot2050/iot2050.env b/board/siemens/iot2050/iot2050.env
index caa9f80e3fca..c8b855852da4 100644
--- a/board/siemens/iot2050/iot2050.env
+++ b/board/siemens/iot2050/iot2050.env
@@ -17,3 +17,12 @@ start_watchdog=
wdt start ${watchdog_timeout_ms};
echo Watchdog started, timeout ${watchdog_timeout_ms} ms;
fi
+
+/*
+ * TODO: Implement a permanent solution for eMMC detection issues.
+ * After approximately 2 months of operation, the device may fail to detect the
+ * eMMC when rebooting. This command enables the eMMC ECSD reset function on
+ * the board, providing a temporary workaround to reset the eMMC if detection
+ * issues occur.
+ */
+mmc_reset_enable=mmc rst-function 1 1 || true
diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig
index 4fc3bcb56b8f..d3ba26705d33 100644
--- a/configs/iot2050_defconfig
+++ b/configs/iot2050_defconfig
@@ -39,7 +39,7 @@ CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_FLUSH_STDIN=y
CONFIG_AUTOBOOT_PROMPT="Hit SPACE to stop autoboot in %d seconds...\n"
CONFIG_AUTOBOOT_STOP_STR=" "
-CONFIG_BOOTCOMMAND="run start_watchdog; run distro_bootcmd"
+CONFIG_BOOTCOMMAND="run start_watchdog; run mmc_reset_enable; run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_MAX_SIZE=0x58000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
@@ -68,6 +68,7 @@ CONFIG_CMD_DFU=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_CMD_PCI=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_USB=y
2 changes: 2 additions & 0 deletions recipes-bsp/u-boot/u-boot-iot2050_2023.10.bb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ SRC_URI += " \
file://0009-dts-iot2050-Sync-kernel-dts-to-u-boot.patch \
file://0010-dts-iot2050-Support-new-IOT2050-SM-variant.patch \
file://0011-arm-dts-iot2050-Disable-lock-step-mode-for-all-iot20.patch \
file://0012-qspi-iot2050-Add-temporary-workaround-for-the-QSPI-i.patch \
file://0013-board-iot2050-Reset-the-eMMC-when-it-isn-t-reachable.patch \
"

SRC_URI[sha256sum] = "e00e6c6f014e046101739d08d06f328811cebcf5ae101348f409cbbd55ce6900"
Expand Down