Commit 76bfc7cc authored by Huijin Park's avatar Huijin Park Committed by Ulf Hansson
Browse files

mmc: core: adjust polling interval for CMD1



In mmc_send_op_cond(), loops are continuously performed at the same
interval of 10 ms.  However the behaviour is not good for some eMMC
which can be out from a busy state earlier than 10 ms if normal.

Rather than fixing about the interval time in mmc_send_op_cond(),
let's instead convert into using the common __mmc_poll_for_busy().

The reason for adjusting the interval time is that it is important
to reduce the eMMC initialization time, especially in devices that
use eMMC as rootfs.

Test log(eMMC:KLM8G1GETF-B041):

before: 12 ms (0.311016 - 0.298729)
[    0.295823] mmc0: starting CMD0 arg 00000000 flags 000000c0
[    0.298729] mmc0: starting CMD1 arg 40000080 flags 000000e1<-start
[    0.311016] mmc0: starting CMD1 arg 40000080 flags 000000e1<-finish
[    0.311336] mmc0: starting CMD2 arg 00000000 flags 00000007

after: 2 ms (0.301270 - 0.298762)
[    0.295862] mmc0: starting CMD0 arg 00000000 flags 000000c0
[    0.298762] mmc0: starting CMD1 arg 40000080 flags 000000e1<-start
[    0.299067] mmc0: starting CMD1 arg 40000080 flags 000000e1
[    0.299441] mmc0: starting CMD1 arg 40000080 flags 000000e1
[    0.299879] mmc0: starting CMD1 arg 40000080 flags 000000e1
[    0.300446] mmc0: starting CMD1 arg 40000080 flags 000000e1
[    0.301270] mmc0: starting CMD1 arg 40000080 flags 000000e1<-finish
[    0.301572] mmc0: starting CMD2 arg 00000000 flags 00000007

Signed-off-by: default avatarHuijin Park <huijin.park@samsung.com>
Link: https://lore.kernel.org/r/20211104063231.2115-3-huijin.park@samsung.com


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 2ebbdace
Loading
Loading
Loading
Loading
+54 −29
Original line number Diff line number Diff line
@@ -58,6 +58,12 @@ struct mmc_busy_data {
	enum mmc_busy_cmd busy_cmd;
};

struct mmc_op_cond_busy_data {
	struct mmc_host *host;
	u32 ocr;
	struct mmc_command *cmd;
};

int __mmc_send_status(struct mmc_card *card, u32 *status, unsigned int retries)
{
	int err;
@@ -173,32 +179,31 @@ int mmc_go_idle(struct mmc_host *host)
	return err;
}

int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
static int __mmc_send_op_cond_cb(void *cb_data, bool *busy)
{
	struct mmc_command cmd = {};
	int i, err = 0;
	struct mmc_op_cond_busy_data *data = cb_data;
	struct mmc_host *host = data->host;
	struct mmc_command *cmd = data->cmd;
	u32 ocr = data->ocr;
	int err = 0;

	cmd.opcode = MMC_SEND_OP_COND;
	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;

	for (i = 100; i; i--) {
		err = mmc_wait_for_cmd(host, &cmd, 0);
	err = mmc_wait_for_cmd(host, cmd, 0);
	if (err)
			break;
		return err;

		/* wait until reset completes */
	if (mmc_host_is_spi(host)) {
			if (!(cmd.resp[0] & R1_SPI_IDLE))
				break;
		if (!(cmd->resp[0] & R1_SPI_IDLE)) {
			*busy = false;
			return 0;
		}
	} else {
			if (cmd.resp[0] & MMC_CARD_BUSY)
				break;
		if (cmd->resp[0] & MMC_CARD_BUSY) {
			*busy = false;
			return 0;
		}
	}

		err = -ETIMEDOUT;

		mmc_delay(10);
	*busy = true;

	/*
	 * According to eMMC specification v5.1 section 6.4.3, we
@@ -208,9 +213,29 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
	 * the eMMC device is busy.
	 */
	if (!ocr && !mmc_host_is_spi(host))
			cmd.arg = cmd.resp[0] | BIT(30);
		cmd->arg = cmd->resp[0] | BIT(30);

	return 0;
}

int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
{
	struct mmc_command cmd = {};
	int err = 0;
	struct mmc_op_cond_busy_data cb_data = {
		.host = host,
		.ocr = ocr,
		.cmd = &cmd
	};

	cmd.opcode = MMC_SEND_OP_COND;
	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;

	err = __mmc_poll_for_busy(host, 1000, &__mmc_send_op_cond_cb, &cb_data);
	if (err)
		return err;

	if (rocr && !mmc_host_is_spi(host))
		*rocr = cmd.resp[0];