mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/4] Add a struct mci_cmd::busy_timeout member
@ 2024-10-31  9:27 Sebastien Bourdelin
  2024-10-31  9:27 ` [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd Sebastien Bourdelin
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-10-31  9:27 UTC (permalink / raw)
  To: barebox; +Cc: oss-contrib, sebastien.bourdelin, Sebastien Bourdelin

From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

This patch series introduce the busy_timeout member as part of the
struct mci_cmd and fix the SDHCI timeout value for the BCM2711 SoC.

It comes as a first step to [1] and allow sdhci drivers to define their
timeout value.

[1] https://github.com/barebox/barebox/blob/master/drivers/mci/mci-core.c#L2109

Sebastien Bourdelin (4):
  mci: add a busy_timeout member to the struct mci_cmd
  mci: zeroed all structs mci_cmd instances
  mci: sdhci: use the busy_timeout value in the sdhci_wait_idle
    functions
  mci: bcm2835: set timeout value to 100ms

 arch/arm/mach-socfpga/arria10-xload-emmc.c |  2 +-
 drivers/mci/dwcmshc-sdhci.c                |  2 +-
 drivers/mci/imx-esdhc-pbl.c                |  4 +--
 drivers/mci/mci-bcm2835.c                  |  4 +++
 drivers/mci/mci-core.c                     | 34 +++++++++++-----------
 drivers/mci/sdhci.c                        | 14 +++++++--
 drivers/mci/sdhci.h                        |  2 ++
 drivers/mci/stm32_sdmmc2.c                 |  2 +-
 include/mci.h                              |  1 +
 9 files changed, 41 insertions(+), 24 deletions(-)

-- 
2.46.2




^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd
  2024-10-31  9:27 [PATCH 0/4] Add a struct mci_cmd::busy_timeout member Sebastien Bourdelin
@ 2024-10-31  9:27 ` Sebastien Bourdelin
  2024-11-06 13:57   ` Ahmad Fatoum
  2024-10-31  9:27 ` [PATCH 2/4] mci: zeroed all structs mci_cmd instances Sebastien Bourdelin
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-10-31  9:27 UTC (permalink / raw)
  To: barebox; +Cc: oss-contrib, sebastien.bourdelin, Sebastien Bourdelin

From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

This commit extends the struct mci_cmd to add a new busy_timeout member.

Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
---
 include/mci.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/mci.h b/include/mci.h
index cd01e2f992..f607ef1b74 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -471,6 +471,7 @@ struct mci_cmd {
 	unsigned cmdidx;	/**< Command to be sent to the SD/MMC card */
 	unsigned resp_type;	/**< Type of expected response, refer MMC_RSP_* macros */
 	unsigned cmdarg;	/**< Command's arguments */
+	unsigned busy_timeout;	/**< Busy timeout in ms */
 	unsigned response[4];	/**< card's response */
 };
 
-- 
2.46.2




^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/4] mci: zeroed all structs mci_cmd instances
  2024-10-31  9:27 [PATCH 0/4] Add a struct mci_cmd::busy_timeout member Sebastien Bourdelin
  2024-10-31  9:27 ` [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd Sebastien Bourdelin
@ 2024-10-31  9:27 ` Sebastien Bourdelin
  2024-11-06 13:57   ` Ahmad Fatoum
  2024-10-31  9:27 ` [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions Sebastien Bourdelin
  2024-10-31  9:27 ` [PATCH 4/4] mci: bcm2835: set timeout value to 100ms Sebastien Bourdelin
  3 siblings, 1 reply; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-10-31  9:27 UTC (permalink / raw)
  To: barebox; +Cc: oss-contrib, sebastien.bourdelin, Sebastien Bourdelin

From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

All structs mci_cmd should be init to zero to avoid error while using
the busy_timeout value.

Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
---
 arch/arm/mach-socfpga/arria10-xload-emmc.c |  2 +-
 drivers/mci/dwcmshc-sdhci.c                |  2 +-
 drivers/mci/imx-esdhc-pbl.c                |  4 +--
 drivers/mci/mci-core.c                     | 34 +++++++++++-----------
 drivers/mci/stm32_sdmmc2.c                 |  2 +-
 5 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-socfpga/arria10-xload-emmc.c b/arch/arm/mach-socfpga/arria10-xload-emmc.c
index ed24faf9bf..61774c6174 100644
--- a/arch/arm/mach-socfpga/arria10-xload-emmc.c
+++ b/arch/arm/mach-socfpga/arria10-xload-emmc.c
@@ -178,7 +178,7 @@ static int dwmci_cmd(struct mci_cmd *cmd, struct mci_data *data)
 
 int arria10_read_blocks(void *dst, int blocknum, size_t len)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	int ret;
 	int blocks;
diff --git a/drivers/mci/dwcmshc-sdhci.c b/drivers/mci/dwcmshc-sdhci.c
index 010d376421..a7306fdb44 100644
--- a/drivers/mci/dwcmshc-sdhci.c
+++ b/drivers/mci/dwcmshc-sdhci.c
@@ -52,7 +52,7 @@ static int do_abort_sequence(struct mci_host *mci, struct mci_cmd *current_cmd)
 {
 	int ret = 0;
 	struct dwcmshc_host *host = priv_from_mci_host(mci);
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	u64 start;
 
 	mci_setup_cmd(&cmd, MMC_CMD_STOP_TRANSMISSION, 0, MMC_RSP_R1b);
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 5b1d9a3cf4..0e4f96d2de 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -35,7 +35,7 @@ static u8 ext_csd[512] __aligned(64);
 
 static int esdhc_send_ext_csd(struct fsl_esdhc_host *host)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 
 	cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
@@ -67,7 +67,7 @@ static bool __maybe_unused esdhc_bootpart_active(struct fsl_esdhc_host *host)
 
 static int esdhc_read_blocks(struct fsl_esdhc_host *host, void *dst, size_t len)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	u32 val;
 	int ret;
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 48a3df9ec9..a6c304c1bd 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -119,7 +119,7 @@ static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigne
  */
 static int mci_set_dsr(struct mci *mci)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 
 	mci_setup_cmd(&cmd, MMC_CMD_SET_DSR,
 			(mci->host->dsr_val >> 16) | 0xffff, MMC_RSP_NONE);
@@ -134,7 +134,7 @@ static int mci_set_dsr(struct mci *mci)
  */
 static int mci_set_blocklen(struct mci *mci, unsigned len)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 
 	if (mci->host->timing == MMC_TIMING_MMC_DDR52)
 		return 0;
@@ -148,7 +148,7 @@ static void *sector_buf;
 static int mci_send_status(struct mci *mci, unsigned int *status)
 {
 	struct mci_host *host = mci->host;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int ret;
 
 	/*
@@ -172,7 +172,7 @@ static int mci_send_status(struct mci *mci, unsigned int *status)
 static int mci_app_sd_status(struct mci *mci, __be32 *ssr)
 {
 	int err;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 
 	cmd.cmdidx = MMC_CMD_APP_CMD;
@@ -272,7 +272,7 @@ static int mci_poll_until_ready(struct mci *mci, int timeout_ms)
 static int mci_block_write(struct mci *mci, const void *src, int blocknum,
 	int blocks)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	unsigned mmccmd;
 	int ret;
@@ -374,7 +374,7 @@ static int mci_block_erase(struct mci *card, unsigned int from,
 static int mci_read_block(struct mci *mci, void *dst, int blocknum,
 		int blocks)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	int ret;
 	unsigned mmccmd;
@@ -411,7 +411,7 @@ static int mci_read_block(struct mci *mci, void *dst, int blocknum,
  */
 static int mci_go_idle(struct mci *mci)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int err;
 
 	udelay(1000);
@@ -431,7 +431,7 @@ static int mci_go_idle(struct mci *mci)
 
 static int sdio_send_op_cond(struct mci *mci)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 
 	mci_setup_cmd(&cmd, SD_IO_SEND_OP_COND, 0, MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR);
 
@@ -446,7 +446,7 @@ static int sdio_send_op_cond(struct mci *mci)
 static int sd_send_op_cond(struct mci *mci)
 {
 	struct mci_host *host = mci->host;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int timeout = 1000;
 	int err;
 	unsigned voltages;
@@ -521,7 +521,7 @@ static int sd_send_op_cond(struct mci *mci)
 static int mmc_send_op_cond(struct mci *mci)
 {
 	struct mci_host *host = mci->host;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int timeout = 1000;
 	int err;
 
@@ -566,7 +566,7 @@ static int mmc_send_op_cond(struct mci *mci)
  */
 int mci_send_ext_csd(struct mci *mci, char *ext_csd)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 
 	/* Get the Card Status Register */
@@ -595,7 +595,7 @@ int mci_send_ext_csd(struct mci *mci, char *ext_csd)
 int mci_switch(struct mci *mci, unsigned index, unsigned value)
 {
 	unsigned int status;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int ret;
 
 	mci_setup_cmd(&cmd, MMC_CMD_SWITCH,
@@ -840,7 +840,7 @@ static int mmc_change_freq(struct mci *mci)
 static int sd_switch(struct mci *mci, unsigned mode, unsigned group,
 			unsigned value, uint8_t *resp)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	unsigned arg;
 
@@ -909,7 +909,7 @@ static int sd_read_ssr(struct mci *mci)
  */
 static int sd_change_freq(struct mci *mci)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	struct mci_data data;
 	struct mci_host *host = mci->host;
 	uint32_t *switch_status = sector_buf;
@@ -1387,7 +1387,7 @@ static char *mci_version_string(struct mci *mci)
 
 static int mci_startup_sd(struct mci *mci)
 {
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int err;
 
 	if (mci_caps(mci) & MMC_CAP_4_BIT_DATA) {
@@ -1782,7 +1782,7 @@ static int mci_startup_mmc(struct mci *mci)
 static int mci_startup(struct mci *mci)
 {
 	struct mci_host *host = mci->host;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int err;
 
 	if (IS_ENABLED(CONFIG_MMC_SPI_CRC_ON) && mmc_host_is_spi(host)) { /* enable CRC check for spi */
@@ -1924,7 +1924,7 @@ static int mci_startup(struct mci *mci)
 static int sd_send_if_cond(struct mci *mci)
 {
 	struct mci_host *host = mci->host;
-	struct mci_cmd cmd;
+	struct mci_cmd cmd = {};
 	int err;
 
 	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
diff --git a/drivers/mci/stm32_sdmmc2.c b/drivers/mci/stm32_sdmmc2.c
index 822416c457..64a7171d2c 100644
--- a/drivers/mci/stm32_sdmmc2.c
+++ b/drivers/mci/stm32_sdmmc2.c
@@ -512,7 +512,7 @@ static int stm32_sdmmc2_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
 	 * shall be send on cmd or data errors.
 	 */
 	if (ret && cmd->cmdidx != MMC_CMD_STOP_TRANSMISSION) {
-		struct mci_cmd stop_cmd;
+		struct mci_cmd stop_cmd = {};
 
 		stop_cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 		stop_cmd.cmdarg = 0;
-- 
2.46.2




^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions
  2024-10-31  9:27 [PATCH 0/4] Add a struct mci_cmd::busy_timeout member Sebastien Bourdelin
  2024-10-31  9:27 ` [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd Sebastien Bourdelin
  2024-10-31  9:27 ` [PATCH 2/4] mci: zeroed all structs mci_cmd instances Sebastien Bourdelin
@ 2024-10-31  9:27 ` Sebastien Bourdelin
  2024-11-06 14:00   ` Ahmad Fatoum
  2024-10-31  9:27 ` [PATCH 4/4] mci: bcm2835: set timeout value to 100ms Sebastien Bourdelin
  3 siblings, 1 reply; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-10-31  9:27 UTC (permalink / raw)
  To: barebox; +Cc: oss-contrib, sebastien.bourdelin, Sebastien Bourdelin

From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

The busy_timeout value is used by the sdhci_wait_idle and
sdhci_wait_idle_data functions to define the timeout to wait on when
send a command to the controller.

The default value remains unchanged and is set to 10ms.

Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
---
 drivers/mci/sdhci.c | 14 ++++++++++++--
 drivers/mci/sdhci.h |  2 ++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/mci/sdhci.c b/drivers/mci/sdhci.c
index fe033583ad..1425c72ef5 100644
--- a/drivers/mci/sdhci.c
+++ b/drivers/mci/sdhci.c
@@ -796,9 +796,11 @@ void sdhci_enable_clk(struct sdhci *host, u16 clk)
 int sdhci_wait_idle(struct sdhci *host, struct mci_cmd *cmd, struct mci_data *data)
 {
 	u32 mask;
+	unsigned timeout_ms;
 	int ret;
 
 	mask = SDHCI_CMD_INHIBIT_CMD;
+	timeout_ms = SDHCI_CMD_DEFAULT_BUSY_TIMEOUT;
 
 	if (data || (cmd && (cmd->resp_type & MMC_RSP_BUSY)))
 		mask |= SDHCI_CMD_INHIBIT_DATA;
@@ -806,7 +808,10 @@ int sdhci_wait_idle(struct sdhci *host, struct mci_cmd *cmd, struct mci_data *da
 	if (cmd && cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 		mask &= ~SDHCI_CMD_INHIBIT_DATA;
 
-	ret = wait_on_timeout(10 * MSECOND,
+	if (cmd && cmd->busy_timeout != 0)
+		timeout_ms = cmd->busy_timeout;
+
+	ret = wait_on_timeout(timeout_ms * MSECOND,
 			!(sdhci_read32(host, SDHCI_PRESENT_STATE) & mask));
 
 	if (ret) {
@@ -821,14 +826,19 @@ int sdhci_wait_idle(struct sdhci *host, struct mci_cmd *cmd, struct mci_data *da
 int sdhci_wait_idle_data(struct sdhci *host, struct mci_cmd *cmd)
 {
 	u32 mask;
+	unsigned timeout_ms;
 	int ret;
 
 	mask = SDHCI_CMD_INHIBIT_CMD | SDHCI_CMD_INHIBIT_DATA;
+	timeout_ms = SDHCI_CMD_DEFAULT_BUSY_TIMEOUT;
 
 	if (cmd && cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 		mask &= ~SDHCI_CMD_INHIBIT_DATA;
 
-	ret = wait_on_timeout(10 * MSECOND,
+	if (cmd && cmd->busy_timeout != 0)
+		timeout_ms = cmd->busy_timeout;
+
+	ret = wait_on_timeout(timeout_ms * MSECOND,
 			!(sdhci_read32(host, SDHCI_PRESENT_STATE) & mask));
 
 	if (ret) {
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
index 5de85239b1..757840acc7 100644
--- a/drivers/mci/sdhci.h
+++ b/drivers/mci/sdhci.h
@@ -200,6 +200,8 @@
 #define SDHCI_MAX_DIV_SPEC_200	256
 #define SDHCI_MAX_DIV_SPEC_300	2046
 
+#define SDHCI_CMD_DEFAULT_BUSY_TIMEOUT 10
+
 struct sdhci {
 	u32 (*read32)(struct sdhci *host, int reg);
 	u16 (*read16)(struct sdhci *host, int reg);
-- 
2.46.2




^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/4] mci: bcm2835: set timeout value to 100ms
  2024-10-31  9:27 [PATCH 0/4] Add a struct mci_cmd::busy_timeout member Sebastien Bourdelin
                   ` (2 preceding siblings ...)
  2024-10-31  9:27 ` [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions Sebastien Bourdelin
@ 2024-10-31  9:27 ` Sebastien Bourdelin
  2024-11-04 12:27   ` Sascha Hauer
  2024-11-06 14:01   ` Ahmad Fatoum
  3 siblings, 2 replies; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-10-31  9:27 UTC (permalink / raw)
  To: barebox; +Cc: oss-contrib, sebastien.bourdelin, Sebastien Bourdelin

From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

As mentionned in the Raspberry Pi4 bootrom Changelog [1]:
"Increase timeout of early SD/EMMC commands to 100ms".
The BCM2711 SDHCI can take up to 100ms to complete a command.

Without this change, we had noticed that Barebox sometime stay stucked
on a timeout error while trying to boot Linux from the eMMC.

[1] https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware-2711/release-notes.md#2022-03-10---promote-the-2022-03-10-beta-release-to-lateststable

Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
---
 drivers/mci/mci-bcm2835.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index cbf99ee7ca..3b086ed22c 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -128,6 +128,10 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
 		block_data |= data->blocksize;
 	}
 
+	/* BCM2xxx SDHCI might take up to 100ms to complete a command */
+	if (cmd != NULL)
+		cmd->busy_timeout = 100;
+
 	ret = sdhci_wait_idle_data(&host->sdhci, cmd);
 	if (ret)
 		return ret;
-- 
2.46.2




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] mci: bcm2835: set timeout value to 100ms
  2024-10-31  9:27 ` [PATCH 4/4] mci: bcm2835: set timeout value to 100ms Sebastien Bourdelin
@ 2024-11-04 12:27   ` Sascha Hauer
  2024-11-06 12:57     ` Sebastien Bourdelin
  2024-11-06 14:01   ` Ahmad Fatoum
  1 sibling, 1 reply; 11+ messages in thread
From: Sascha Hauer @ 2024-11-04 12:27 UTC (permalink / raw)
  To: Sebastien Bourdelin; +Cc: barebox, oss-contrib, Sebastien Bourdelin

On Thu, Oct 31, 2024 at 10:27:21AM +0100, Sebastien Bourdelin wrote:
> From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> 
> As mentionned in the Raspberry Pi4 bootrom Changelog [1]:
> "Increase timeout of early SD/EMMC commands to 100ms".
> The BCM2711 SDHCI can take up to 100ms to complete a command.
> 
> Without this change, we had noticed that Barebox sometime stay stucked
> on a timeout error while trying to boot Linux from the eMMC.
> 
> [1] https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware-2711/release-notes.md#2022-03-10---promote-the-2022-03-10-beta-release-to-lateststable
> 
> Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> ---
>  drivers/mci/mci-bcm2835.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
> index cbf99ee7ca..3b086ed22c 100644
> --- a/drivers/mci/mci-bcm2835.c
> +++ b/drivers/mci/mci-bcm2835.c
> @@ -128,6 +128,10 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
>  		block_data |= data->blocksize;
>  	}
>  
> +	/* BCM2xxx SDHCI might take up to 100ms to complete a command */
> +	if (cmd != NULL)
> +		cmd->busy_timeout = 100;

Do we need this for all commands or just some specific ones?

cmd is always non NULL, no need to check.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] mci: bcm2835: set timeout value to 100ms
  2024-11-04 12:27   ` Sascha Hauer
@ 2024-11-06 12:57     ` Sebastien Bourdelin
  0 siblings, 0 replies; 11+ messages in thread
From: Sebastien Bourdelin @ 2024-11-06 12:57 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, oss-contrib, Sebastien Bourdelin

On Mon Nov 4, 2024 at 1:27 PM CET, Sascha Hauer wrote:
> On Thu, Oct 31, 2024 at 10:27:21AM +0100, Sebastien Bourdelin wrote:
> > From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> > 
> > As mentionned in the Raspberry Pi4 bootrom Changelog [1]:
> > "Increase timeout of early SD/EMMC commands to 100ms".
> > The BCM2711 SDHCI can take up to 100ms to complete a command.
> > 
> > Without this change, we had noticed that Barebox sometime stay stucked
> > on a timeout error while trying to boot Linux from the eMMC.
> > 
> > [1] https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware-2711/release-notes.md#2022-03-10---promote-the-2022-03-10-beta-release-to-lateststable
> > 
> > Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> > ---
> >  drivers/mci/mci-bcm2835.c | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
> > index cbf99ee7ca..3b086ed22c 100644
> > --- a/drivers/mci/mci-bcm2835.c
> > +++ b/drivers/mci/mci-bcm2835.c
> > @@ -128,6 +128,10 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
> >  		block_data |= data->blocksize;
> >  	}
> >  
> > +	/* BCM2xxx SDHCI might take up to 100ms to complete a command */
> > +	if (cmd != NULL)
> > +		cmd->busy_timeout = 100;
>
> Do we need this for all commands or just some specific ones?
I actually have no idea, the CM4s datasheet doesn't give much
informations regarding the eMMC controller and we just found that
information in the rpi-eeprom changelog, and saw it was also the defaut
timeout value used in U-boot [1].
After this change, we haven't been able to reproduce the issue.

We know for sure this issue happens at least on a read
command.

[1] https://github.com/u-boot/u-boot/blob/master/drivers/mmc/sdhci.c#L195
>
> cmd is always non NULL, no need to check.
Ok, i can send a v2 for that, just let me know if my explanation for
your first question is enough. 
>
> Sascha




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd
  2024-10-31  9:27 ` [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd Sebastien Bourdelin
@ 2024-11-06 13:57   ` Ahmad Fatoum
  0 siblings, 0 replies; 11+ messages in thread
From: Ahmad Fatoum @ 2024-11-06 13:57 UTC (permalink / raw)
  To: Sebastien Bourdelin, barebox; +Cc: oss-contrib, Sebastien Bourdelin

On 31.10.24 10:27, Sebastien Bourdelin wrote:
> From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> 
> This commit extends the struct mci_cmd to add a new busy_timeout member.
> 
> Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  include/mci.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/mci.h b/include/mci.h
> index cd01e2f992..f607ef1b74 100644
> --- a/include/mci.h
> +++ b/include/mci.h
> @@ -471,6 +471,7 @@ struct mci_cmd {
>  	unsigned cmdidx;	/**< Command to be sent to the SD/MMC card */
>  	unsigned resp_type;	/**< Type of expected response, refer MMC_RSP_* macros */
>  	unsigned cmdarg;	/**< Command's arguments */
> +	unsigned busy_timeout;	/**< Busy timeout in ms */
>  	unsigned response[4];	/**< card's response */
>  };
>  


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] mci: zeroed all structs mci_cmd instances
  2024-10-31  9:27 ` [PATCH 2/4] mci: zeroed all structs mci_cmd instances Sebastien Bourdelin
@ 2024-11-06 13:57   ` Ahmad Fatoum
  0 siblings, 0 replies; 11+ messages in thread
From: Ahmad Fatoum @ 2024-11-06 13:57 UTC (permalink / raw)
  To: Sebastien Bourdelin, barebox; +Cc: oss-contrib, Sebastien Bourdelin

On 31.10.24 10:27, Sebastien Bourdelin wrote:
> From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> 
> All structs mci_cmd should be init to zero to avoid error while using
> the busy_timeout value.

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> 
> Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> ---
>  arch/arm/mach-socfpga/arria10-xload-emmc.c |  2 +-
>  drivers/mci/dwcmshc-sdhci.c                |  2 +-
>  drivers/mci/imx-esdhc-pbl.c                |  4 +--
>  drivers/mci/mci-core.c                     | 34 +++++++++++-----------
>  drivers/mci/stm32_sdmmc2.c                 |  2 +-
>  5 files changed, 22 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/arm/mach-socfpga/arria10-xload-emmc.c b/arch/arm/mach-socfpga/arria10-xload-emmc.c
> index ed24faf9bf..61774c6174 100644
> --- a/arch/arm/mach-socfpga/arria10-xload-emmc.c
> +++ b/arch/arm/mach-socfpga/arria10-xload-emmc.c
> @@ -178,7 +178,7 @@ static int dwmci_cmd(struct mci_cmd *cmd, struct mci_data *data)
>  
>  int arria10_read_blocks(void *dst, int blocknum, size_t len)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	int ret;
>  	int blocks;
> diff --git a/drivers/mci/dwcmshc-sdhci.c b/drivers/mci/dwcmshc-sdhci.c
> index 010d376421..a7306fdb44 100644
> --- a/drivers/mci/dwcmshc-sdhci.c
> +++ b/drivers/mci/dwcmshc-sdhci.c
> @@ -52,7 +52,7 @@ static int do_abort_sequence(struct mci_host *mci, struct mci_cmd *current_cmd)
>  {
>  	int ret = 0;
>  	struct dwcmshc_host *host = priv_from_mci_host(mci);
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	u64 start;
>  
>  	mci_setup_cmd(&cmd, MMC_CMD_STOP_TRANSMISSION, 0, MMC_RSP_R1b);
> diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
> index 5b1d9a3cf4..0e4f96d2de 100644
> --- a/drivers/mci/imx-esdhc-pbl.c
> +++ b/drivers/mci/imx-esdhc-pbl.c
> @@ -35,7 +35,7 @@ static u8 ext_csd[512] __aligned(64);
>  
>  static int esdhc_send_ext_csd(struct fsl_esdhc_host *host)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  
>  	cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
> @@ -67,7 +67,7 @@ static bool __maybe_unused esdhc_bootpart_active(struct fsl_esdhc_host *host)
>  
>  static int esdhc_read_blocks(struct fsl_esdhc_host *host, void *dst, size_t len)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	u32 val;
>  	int ret;
> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
> index 48a3df9ec9..a6c304c1bd 100644
> --- a/drivers/mci/mci-core.c
> +++ b/drivers/mci/mci-core.c
> @@ -119,7 +119,7 @@ static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigne
>   */
>  static int mci_set_dsr(struct mci *mci)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  
>  	mci_setup_cmd(&cmd, MMC_CMD_SET_DSR,
>  			(mci->host->dsr_val >> 16) | 0xffff, MMC_RSP_NONE);
> @@ -134,7 +134,7 @@ static int mci_set_dsr(struct mci *mci)
>   */
>  static int mci_set_blocklen(struct mci *mci, unsigned len)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  
>  	if (mci->host->timing == MMC_TIMING_MMC_DDR52)
>  		return 0;
> @@ -148,7 +148,7 @@ static void *sector_buf;
>  static int mci_send_status(struct mci *mci, unsigned int *status)
>  {
>  	struct mci_host *host = mci->host;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int ret;
>  
>  	/*
> @@ -172,7 +172,7 @@ static int mci_send_status(struct mci *mci, unsigned int *status)
>  static int mci_app_sd_status(struct mci *mci, __be32 *ssr)
>  {
>  	int err;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  
>  	cmd.cmdidx = MMC_CMD_APP_CMD;
> @@ -272,7 +272,7 @@ static int mci_poll_until_ready(struct mci *mci, int timeout_ms)
>  static int mci_block_write(struct mci *mci, const void *src, int blocknum,
>  	int blocks)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	unsigned mmccmd;
>  	int ret;
> @@ -374,7 +374,7 @@ static int mci_block_erase(struct mci *card, unsigned int from,
>  static int mci_read_block(struct mci *mci, void *dst, int blocknum,
>  		int blocks)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	int ret;
>  	unsigned mmccmd;
> @@ -411,7 +411,7 @@ static int mci_read_block(struct mci *mci, void *dst, int blocknum,
>   */
>  static int mci_go_idle(struct mci *mci)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int err;
>  
>  	udelay(1000);
> @@ -431,7 +431,7 @@ static int mci_go_idle(struct mci *mci)
>  
>  static int sdio_send_op_cond(struct mci *mci)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  
>  	mci_setup_cmd(&cmd, SD_IO_SEND_OP_COND, 0, MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR);
>  
> @@ -446,7 +446,7 @@ static int sdio_send_op_cond(struct mci *mci)
>  static int sd_send_op_cond(struct mci *mci)
>  {
>  	struct mci_host *host = mci->host;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int timeout = 1000;
>  	int err;
>  	unsigned voltages;
> @@ -521,7 +521,7 @@ static int sd_send_op_cond(struct mci *mci)
>  static int mmc_send_op_cond(struct mci *mci)
>  {
>  	struct mci_host *host = mci->host;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int timeout = 1000;
>  	int err;
>  
> @@ -566,7 +566,7 @@ static int mmc_send_op_cond(struct mci *mci)
>   */
>  int mci_send_ext_csd(struct mci *mci, char *ext_csd)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  
>  	/* Get the Card Status Register */
> @@ -595,7 +595,7 @@ int mci_send_ext_csd(struct mci *mci, char *ext_csd)
>  int mci_switch(struct mci *mci, unsigned index, unsigned value)
>  {
>  	unsigned int status;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int ret;
>  
>  	mci_setup_cmd(&cmd, MMC_CMD_SWITCH,
> @@ -840,7 +840,7 @@ static int mmc_change_freq(struct mci *mci)
>  static int sd_switch(struct mci *mci, unsigned mode, unsigned group,
>  			unsigned value, uint8_t *resp)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	unsigned arg;
>  
> @@ -909,7 +909,7 @@ static int sd_read_ssr(struct mci *mci)
>   */
>  static int sd_change_freq(struct mci *mci)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	struct mci_data data;
>  	struct mci_host *host = mci->host;
>  	uint32_t *switch_status = sector_buf;
> @@ -1387,7 +1387,7 @@ static char *mci_version_string(struct mci *mci)
>  
>  static int mci_startup_sd(struct mci *mci)
>  {
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int err;
>  
>  	if (mci_caps(mci) & MMC_CAP_4_BIT_DATA) {
> @@ -1782,7 +1782,7 @@ static int mci_startup_mmc(struct mci *mci)
>  static int mci_startup(struct mci *mci)
>  {
>  	struct mci_host *host = mci->host;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int err;
>  
>  	if (IS_ENABLED(CONFIG_MMC_SPI_CRC_ON) && mmc_host_is_spi(host)) { /* enable CRC check for spi */
> @@ -1924,7 +1924,7 @@ static int mci_startup(struct mci *mci)
>  static int sd_send_if_cond(struct mci *mci)
>  {
>  	struct mci_host *host = mci->host;
> -	struct mci_cmd cmd;
> +	struct mci_cmd cmd = {};
>  	int err;
>  
>  	mci_setup_cmd(&cmd, SD_CMD_SEND_IF_COND,
> diff --git a/drivers/mci/stm32_sdmmc2.c b/drivers/mci/stm32_sdmmc2.c
> index 822416c457..64a7171d2c 100644
> --- a/drivers/mci/stm32_sdmmc2.c
> +++ b/drivers/mci/stm32_sdmmc2.c
> @@ -512,7 +512,7 @@ static int stm32_sdmmc2_send_cmd(struct mci_host *mci, struct mci_cmd *cmd,
>  	 * shall be send on cmd or data errors.
>  	 */
>  	if (ret && cmd->cmdidx != MMC_CMD_STOP_TRANSMISSION) {
> -		struct mci_cmd stop_cmd;
> +		struct mci_cmd stop_cmd = {};
>  
>  		stop_cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
>  		stop_cmd.cmdarg = 0;


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions
  2024-10-31  9:27 ` [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions Sebastien Bourdelin
@ 2024-11-06 14:00   ` Ahmad Fatoum
  0 siblings, 0 replies; 11+ messages in thread
From: Ahmad Fatoum @ 2024-11-06 14:00 UTC (permalink / raw)
  To: Sebastien Bourdelin, barebox; +Cc: oss-contrib, Sebastien Bourdelin

On 31.10.24 10:27, Sebastien Bourdelin wrote:
> From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> 
> The busy_timeout value is used by the sdhci_wait_idle and
> sdhci_wait_idle_data functions to define the timeout to wait on when
> send a command to the controller.
> 
> The default value remains unchanged and is set to 10ms.
> 
> Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

With below point addressed:

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
> index 5de85239b1..757840acc7 100644
> --- a/drivers/mci/sdhci.h
> +++ b/drivers/mci/sdhci.h
> @@ -200,6 +200,8 @@
>  #define SDHCI_MAX_DIV_SPEC_200	256
>  #define SDHCI_MAX_DIV_SPEC_300	2046
>  
> +#define SDHCI_CMD_DEFAULT_BUSY_TIMEOUT 10

Please rename to SDHCI_CMD_DEFAULT_BUSY_TIMEOUT_MS

> +
>  struct sdhci {
>  	u32 (*read32)(struct sdhci *host, int reg);
>  	u16 (*read16)(struct sdhci *host, int reg);


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] mci: bcm2835: set timeout value to 100ms
  2024-10-31  9:27 ` [PATCH 4/4] mci: bcm2835: set timeout value to 100ms Sebastien Bourdelin
  2024-11-04 12:27   ` Sascha Hauer
@ 2024-11-06 14:01   ` Ahmad Fatoum
  1 sibling, 0 replies; 11+ messages in thread
From: Ahmad Fatoum @ 2024-11-06 14:01 UTC (permalink / raw)
  To: Sebastien Bourdelin, barebox; +Cc: oss-contrib, Sebastien Bourdelin

Hello Sebastien,

Thanks for your fix.

On 31.10.24 10:27, Sebastien Bourdelin wrote:
> From: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>
> 
> As mentionned in the Raspberry Pi4 bootrom Changelog [1]:
> "Increase timeout of early SD/EMMC commands to 100ms".
> The BCM2711 SDHCI can take up to 100ms to complete a command.
> 
> Without this change, we had noticed that Barebox sometime stay stucked
> on a timeout error while trying to boot Linux from the eMMC.
> 
> [1] https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware-2711/release-notes.md#2022-03-10---promote-the-2022-03-10-beta-release-to-lateststable
> 
> Signed-off-by: Sebastien Bourdelin <sebastien.bourdelin@rtone.fr>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

Cheers,
Ahmad

> ---
>  drivers/mci/mci-bcm2835.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
> index cbf99ee7ca..3b086ed22c 100644
> --- a/drivers/mci/mci-bcm2835.c
> +++ b/drivers/mci/mci-bcm2835.c
> @@ -128,6 +128,10 @@ static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
>  		block_data |= data->blocksize;
>  	}
>  
> +	/* BCM2xxx SDHCI might take up to 100ms to complete a command */
> +	if (cmd != NULL)
> +		cmd->busy_timeout = 100;
> +
>  	ret = sdhci_wait_idle_data(&host->sdhci, cmd);
>  	if (ret)
>  		return ret;


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-11-06 14:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-31  9:27 [PATCH 0/4] Add a struct mci_cmd::busy_timeout member Sebastien Bourdelin
2024-10-31  9:27 ` [PATCH 1/4] mci: add a busy_timeout member to the struct mci_cmd Sebastien Bourdelin
2024-11-06 13:57   ` Ahmad Fatoum
2024-10-31  9:27 ` [PATCH 2/4] mci: zeroed all structs mci_cmd instances Sebastien Bourdelin
2024-11-06 13:57   ` Ahmad Fatoum
2024-10-31  9:27 ` [PATCH 3/4] mci: sdhci: use the busy_timeout value in the sdhci_wait_idle functions Sebastien Bourdelin
2024-11-06 14:00   ` Ahmad Fatoum
2024-10-31  9:27 ` [PATCH 4/4] mci: bcm2835: set timeout value to 100ms Sebastien Bourdelin
2024-11-04 12:27   ` Sascha Hauer
2024-11-06 12:57     ` Sebastien Bourdelin
2024-11-06 14:01   ` Ahmad Fatoum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox