Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9225176 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[MMC] Add MMC command type flags



Some hosts need to know the command type, so pass it via a set of
flags in cmd->flags.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent a6df590d
Loading
Loading
Loading
Loading
+30 −29
Original line number Original line Diff line number Diff line
@@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,


	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);


	switch(cmd->flags) {
	switch (mmc_rsp_type(cmd->flags)) {
	case MMC_RSP_R1:
	case MMC_RSP_R1:
		mmccmd |= SD_CMD_RT_1;
		mmccmd |= SD_CMD_RT_1;
		break;
		break;
@@ -483,18 +483,8 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
	cmd = mrq->cmd;
	cmd = mrq->cmd;
	cmd->error = MMC_ERR_NONE;
	cmd->error = MMC_ERR_NONE;


	if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) {
	if (cmd->flags & MMC_RSP_PRESENT) {

		if (cmd->flags & MMC_RSP_136) {
		/* Techincally, we should be getting all 48 bits of the response
		 * (SD_RESP1 + SD_RESP2), but because our response omits the CRC,
		 * our data ends up being shifted 8 bits to the right.  In this case,
		 * that means that the OSR data starts at bit 31, so we can just
		 * read RESP0 and return that
		 */

		cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
	}
	else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
			u32 r[4];
			u32 r[4];
			int i;
			int i;


@@ -503,14 +493,25 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
			r[2] = au_readl(host->iobase + SD_RESP1);
			r[2] = au_readl(host->iobase + SD_RESP1);
			r[3] = au_readl(host->iobase + SD_RESP0);
			r[3] = au_readl(host->iobase + SD_RESP0);


		/* The CRC is omitted from the response, so really we only got
			/* The CRC is omitted from the response, so really
		 * 120 bytes, but the engine expects 128 bits, so we have to shift
			 * we only got 120 bytes, but the engine expects
		 * things up
			 * 128 bits, so we have to shift things up
			 */
			 */


			for(i = 0; i < 4; i++) {
			for(i = 0; i < 4; i++) {
				cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
				cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
			if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
				if (i != 3)
					cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
			}
		} else {
			/* Techincally, we should be getting all 48 bits of
			 * the response (SD_RESP1 + SD_RESP2), but because
			 * our response omits the CRC, our data ends up
			 * being shifted 8 bits to the right.  In this case,
			 * that means that the OSR data starts at bit 31,
			 * so we can just read RESP0 and return that
			 */
			cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
		}
		}
	}
	}


+14 −14
Original line number Original line Diff line number Diff line
@@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,


		appcmd.opcode = MMC_APP_CMD;
		appcmd.opcode = MMC_APP_CMD;
		appcmd.arg = rca << 16;
		appcmd.arg = rca << 16;
		appcmd.flags = MMC_RSP_R1;
		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
		appcmd.retries = 0;
		appcmd.retries = 0;
		memset(appcmd.resp, 0, sizeof(appcmd.resp));
		memset(appcmd.resp, 0, sizeof(appcmd.resp));
		appcmd.data = NULL;
		appcmd.data = NULL;
@@ -331,7 +331,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)


	cmd.opcode = MMC_SELECT_CARD;
	cmd.opcode = MMC_SELECT_CARD;
	cmd.arg = card->rca << 16;
	cmd.arg = card->rca << 16;
	cmd.flags = MMC_RSP_R1;
	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;


	err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
	err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
	if (err != MMC_ERR_NONE)
	if (err != MMC_ERR_NONE)
@@ -358,7 +358,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
			struct mmc_command cmd;
			struct mmc_command cmd;
			cmd.opcode = SD_APP_SET_BUS_WIDTH;
			cmd.opcode = SD_APP_SET_BUS_WIDTH;
			cmd.arg = SD_BUS_WIDTH_4;
			cmd.arg = SD_BUS_WIDTH_4;
			cmd.flags = MMC_RSP_R1;
			cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;


			err = mmc_wait_for_app_cmd(host, card->rca, &cmd,
			err = mmc_wait_for_app_cmd(host, card->rca, &cmd,
				CMD_RETRIES);
				CMD_RETRIES);
@@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host)


		cmd.opcode = MMC_SELECT_CARD;
		cmd.opcode = MMC_SELECT_CARD;
		cmd.arg = 0;
		cmd.arg = 0;
		cmd.flags = MMC_RSP_NONE;
		cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;


		mmc_wait_for_cmd(host, &cmd, 0);
		mmc_wait_for_cmd(host, &cmd, 0);
	}
	}
@@ -677,7 +677,7 @@ static void mmc_idle_cards(struct mmc_host *host)


	cmd.opcode = MMC_GO_IDLE_STATE;
	cmd.opcode = MMC_GO_IDLE_STATE;
	cmd.arg = 0;
	cmd.arg = 0;
	cmd.flags = MMC_RSP_NONE;
	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;


	mmc_wait_for_cmd(host, &cmd, 0);
	mmc_wait_for_cmd(host, &cmd, 0);


@@ -738,7 +738,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)


	cmd.opcode = MMC_SEND_OP_COND;
	cmd.opcode = MMC_SEND_OP_COND;
	cmd.arg = ocr;
	cmd.arg = ocr;
	cmd.flags = MMC_RSP_R3;
	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;


	for (i = 100; i; i--) {
	for (i = 100; i; i--) {
		err = mmc_wait_for_cmd(host, &cmd, 0);
		err = mmc_wait_for_cmd(host, &cmd, 0);
@@ -766,7 +766,7 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)


	cmd.opcode = SD_APP_OP_COND;
	cmd.opcode = SD_APP_OP_COND;
	cmd.arg = ocr;
	cmd.arg = ocr;
	cmd.flags = MMC_RSP_R3;
	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;


	for (i = 100; i; i--) {
	for (i = 100; i; i--) {
		err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES);
		err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES);
@@ -805,7 +805,7 @@ static void mmc_discover_cards(struct mmc_host *host)


		cmd.opcode = MMC_ALL_SEND_CID;
		cmd.opcode = MMC_ALL_SEND_CID;
		cmd.arg = 0;
		cmd.arg = 0;
		cmd.flags = MMC_RSP_R2;
		cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;


		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		if (err == MMC_ERR_TIMEOUT) {
		if (err == MMC_ERR_TIMEOUT) {
@@ -835,7 +835,7 @@ static void mmc_discover_cards(struct mmc_host *host)


			cmd.opcode = SD_SEND_RELATIVE_ADDR;
			cmd.opcode = SD_SEND_RELATIVE_ADDR;
			cmd.arg = 0;
			cmd.arg = 0;
			cmd.flags = MMC_RSP_R6;
			cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;


			err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
			err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
			if (err != MMC_ERR_NONE)
			if (err != MMC_ERR_NONE)
@@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host)
		} else {
		} else {
			cmd.opcode = MMC_SET_RELATIVE_ADDR;
			cmd.opcode = MMC_SET_RELATIVE_ADDR;
			cmd.arg = card->rca << 16;
			cmd.arg = card->rca << 16;
			cmd.flags = MMC_RSP_R1;
			cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;


			err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
			err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
			if (err != MMC_ERR_NONE)
			if (err != MMC_ERR_NONE)
@@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host)


		cmd.opcode = MMC_SEND_CSD;
		cmd.opcode = MMC_SEND_CSD;
		cmd.arg = card->rca << 16;
		cmd.arg = card->rca << 16;
		cmd.flags = MMC_RSP_R2;
		cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;


		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		if (err != MMC_ERR_NONE) {
		if (err != MMC_ERR_NONE) {
@@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host)


		cmd.opcode = MMC_APP_CMD;
		cmd.opcode = MMC_APP_CMD;
		cmd.arg = card->rca << 16;
		cmd.arg = card->rca << 16;
		cmd.flags = MMC_RSP_R1;
		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;


		err = mmc_wait_for_cmd(host, &cmd, 0);
		err = mmc_wait_for_cmd(host, &cmd, 0);
		if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
		if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) {
@@ -932,7 +932,7 @@ static void mmc_read_scrs(struct mmc_host *host)


		cmd.opcode = SD_APP_SEND_SCR;
		cmd.opcode = SD_APP_SEND_SCR;
		cmd.arg = 0;
		cmd.arg = 0;
		cmd.flags = MMC_RSP_R1;
		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;


		memset(&data, 0, sizeof(struct mmc_data));
		memset(&data, 0, sizeof(struct mmc_data));


@@ -1003,7 +1003,7 @@ static void mmc_check_cards(struct mmc_host *host)


		cmd.opcode = MMC_SEND_STATUS;
		cmd.opcode = MMC_SEND_STATUS;
		cmd.arg = card->rca << 16;
		cmd.arg = card->rca << 16;
		cmd.flags = MMC_RSP_R1;
		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;


		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
		if (err == MMC_ERR_NONE)
		if (err == MMC_ERR_NONE)
+4 −4
Original line number Original line Diff line number Diff line
@@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
		brq.mrq.data = &brq.data;
		brq.mrq.data = &brq.data;


		brq.cmd.arg = req->sector << 9;
		brq.cmd.arg = req->sector << 9;
		brq.cmd.flags = MMC_RSP_R1;
		brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
		brq.data.timeout_ns = card->csd.tacc_ns * 10;
		brq.data.timeout_ns = card->csd.tacc_ns * 10;
		brq.data.timeout_clks = card->csd.tacc_clks * 10;
		brq.data.timeout_clks = card->csd.tacc_clks * 10;
		brq.data.blksz_bits = md->block_bits;
		brq.data.blksz_bits = md->block_bits;
		brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
		brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
		brq.stop.opcode = MMC_STOP_TRANSMISSION;
		brq.stop.opcode = MMC_STOP_TRANSMISSION;
		brq.stop.arg = 0;
		brq.stop.arg = 0;
		brq.stop.flags = MMC_RSP_R1B;
		brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;


		if (rq_data_dir(req) == READ) {
		if (rq_data_dir(req) == READ) {
			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
@@ -223,7 +223,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)


			cmd.opcode = MMC_SEND_STATUS;
			cmd.opcode = MMC_SEND_STATUS;
			cmd.arg = card->rca << 16;
			cmd.arg = card->rca << 16;
			cmd.flags = MMC_RSP_R1;
			cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
			err = mmc_wait_for_cmd(card->host, &cmd, 5);
			err = mmc_wait_for_cmd(card->host, &cmd, 5);
			if (err) {
			if (err) {
				printk(KERN_ERR "%s: error %d requesting status\n",
				printk(KERN_ERR "%s: error %d requesting status\n",
@@ -430,7 +430,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
	mmc_card_claim_host(card);
	mmc_card_claim_host(card);
	cmd.opcode = MMC_SET_BLOCKLEN;
	cmd.opcode = MMC_SET_BLOCKLEN;
	cmd.arg = 1 << md->block_bits;
	cmd.arg = 1 << md->block_bits;
	cmd.flags = MMC_RSP_R1;
	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
	err = mmc_wait_for_cmd(card->host, &cmd, 5);
	err = mmc_wait_for_cmd(card->host, &cmd, 5);
	mmc_card_release_host(card);
	mmc_card_release_host(card);


+3 −8
Original line number Original line Diff line number Diff line
@@ -124,15 +124,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
	}
	}


	c |= cmd->opcode | MCI_CPSM_ENABLE;
	c |= cmd->opcode | MCI_CPSM_ENABLE;
	switch (cmd->flags & MMC_RSP_MASK) {
	if (cmd->flags & MMC_RSP_PRESENT) {
	case MMC_RSP_NONE:
		if (cmd->flags & MMC_RSP_136)
	default:
		break;
	case MMC_RSP_LONG:
			c |= MCI_CPSM_LONGRSP;
			c |= MCI_CPSM_LONGRSP;
	case MMC_RSP_SHORT:
		c |= MCI_CPSM_RESPONSE;
		c |= MCI_CPSM_RESPONSE;
		break;
	}
	}
	if (/*interrupt*/0)
	if (/*interrupt*/0)
		c |= MCI_CPSM_INTERRUPT;
		c |= MCI_CPSM_INTERRUPT;
+5 −4
Original line number Original line Diff line number Diff line
@@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd,
	if (cmd->flags & MMC_RSP_BUSY)
	if (cmd->flags & MMC_RSP_BUSY)
		cmdat |= CMDAT_BUSY;
		cmdat |= CMDAT_BUSY;


	switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
#define RSP_TYPE(x)	((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
	case MMC_RSP_SHORT | MMC_RSP_CRC:
	switch (RSP_TYPE(mmc_resp_type(cmd))) {
	case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */
		cmdat |= CMDAT_RESP_SHORT;
		cmdat |= CMDAT_RESP_SHORT;
		break;
		break;
	case MMC_RSP_SHORT:
	case RSP_TYPE(MMC_RSP_R3):
		cmdat |= CMDAT_RESP_R3;
		cmdat |= CMDAT_RESP_R3;
		break;
		break;
	case MMC_RSP_LONG | MMC_RSP_CRC:
	case RSP_TYPE(MMC_RSP_R2):
		cmdat |= CMDAT_RESP_R2;
		cmdat |= CMDAT_RESP_R2;
		break;
		break;
	default:
	default:
Loading