[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: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
a6df590dd8
commit
e92251762d
|
@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
|
|||
|
||||
u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
|
||||
|
||||
switch(cmd->flags) {
|
||||
switch (mmc_rsp_type(cmd->flags)) {
|
||||
case MMC_RSP_R1:
|
||||
mmccmd |= SD_CMD_RT_1;
|
||||
break;
|
||||
|
@ -483,34 +483,35 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
|
|||
cmd = mrq->cmd;
|
||||
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) {
|
||||
u32 r[4];
|
||||
int i;
|
||||
|
||||
/* 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
|
||||
*/
|
||||
r[0] = au_readl(host->iobase + SD_RESP3);
|
||||
r[1] = au_readl(host->iobase + SD_RESP2);
|
||||
r[2] = au_readl(host->iobase + SD_RESP1);
|
||||
r[3] = au_readl(host->iobase + SD_RESP0);
|
||||
|
||||
cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
|
||||
}
|
||||
else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) {
|
||||
u32 r[4];
|
||||
int i;
|
||||
/* The CRC is omitted from the response, so really
|
||||
* we only got 120 bytes, but the engine expects
|
||||
* 128 bits, so we have to shift things up
|
||||
*/
|
||||
|
||||
r[0] = au_readl(host->iobase + SD_RESP3);
|
||||
r[1] = au_readl(host->iobase + SD_RESP2);
|
||||
r[2] = au_readl(host->iobase + SD_RESP1);
|
||||
r[3] = au_readl(host->iobase + SD_RESP0);
|
||||
|
||||
/* The CRC is omitted from the response, so really we only got
|
||||
* 120 bytes, but the engine expects 128 bits, so we have to shift
|
||||
* things up
|
||||
*/
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
|
||||
if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
|
||||
for(i = 0; i < 4; i++) {
|
||||
cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
|
|||
|
||||
appcmd.opcode = MMC_APP_CMD;
|
||||
appcmd.arg = rca << 16;
|
||||
appcmd.flags = MMC_RSP_R1;
|
||||
appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
||||
appcmd.retries = 0;
|
||||
memset(appcmd.resp, 0, sizeof(appcmd.resp));
|
||||
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.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);
|
||||
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;
|
||||
cmd.opcode = SD_APP_SET_BUS_WIDTH;
|
||||
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,
|
||||
CMD_RETRIES);
|
||||
|
@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host)
|
|||
|
||||
cmd.opcode = MMC_SELECT_CARD;
|
||||
cmd.arg = 0;
|
||||
cmd.flags = MMC_RSP_NONE;
|
||||
cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
|
||||
|
||||
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.arg = 0;
|
||||
cmd.flags = MMC_RSP_NONE;
|
||||
cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
|
||||
|
||||
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.arg = ocr;
|
||||
cmd.flags = MMC_RSP_R3;
|
||||
cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
|
||||
|
||||
for (i = 100; i; i--) {
|
||||
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.arg = ocr;
|
||||
cmd.flags = MMC_RSP_R3;
|
||||
cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
|
||||
|
||||
for (i = 100; i; i--) {
|
||||
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.arg = 0;
|
||||
cmd.flags = MMC_RSP_R2;
|
||||
cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
|
||||
|
||||
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
|
||||
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.arg = 0;
|
||||
cmd.flags = MMC_RSP_R6;
|
||||
cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
|
||||
|
||||
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
|
||||
if (err != MMC_ERR_NONE)
|
||||
|
@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host)
|
|||
} else {
|
||||
cmd.opcode = MMC_SET_RELATIVE_ADDR;
|
||||
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);
|
||||
if (err != MMC_ERR_NONE)
|
||||
|
@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host)
|
|||
|
||||
cmd.opcode = MMC_SEND_CSD;
|
||||
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);
|
||||
if (err != MMC_ERR_NONE) {
|
||||
|
@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host)
|
|||
|
||||
cmd.opcode = MMC_APP_CMD;
|
||||
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);
|
||||
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.arg = 0;
|
||||
cmd.flags = MMC_RSP_R1;
|
||||
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
|
||||
|
||||
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.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);
|
||||
if (err == MMC_ERR_NONE)
|
||||
|
|
|
@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
brq.mrq.data = &brq.data;
|
||||
|
||||
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_clks = card->csd.tacc_clks * 10;
|
||||
brq.data.blksz_bits = md->block_bits;
|
||||
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
|
||||
brq.stop.opcode = MMC_STOP_TRANSMISSION;
|
||||
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) {
|
||||
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.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);
|
||||
if (err) {
|
||||
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);
|
||||
cmd.opcode = MMC_SET_BLOCKLEN;
|
||||
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);
|
||||
mmc_card_release_host(card);
|
||||
|
||||
|
|
|
@ -124,15 +124,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
|
|||
}
|
||||
|
||||
c |= cmd->opcode | MCI_CPSM_ENABLE;
|
||||
switch (cmd->flags & MMC_RSP_MASK) {
|
||||
case MMC_RSP_NONE:
|
||||
default:
|
||||
break;
|
||||
case MMC_RSP_LONG:
|
||||
c |= MCI_CPSM_LONGRSP;
|
||||
case MMC_RSP_SHORT:
|
||||
if (cmd->flags & MMC_RSP_PRESENT) {
|
||||
if (cmd->flags & MMC_RSP_136)
|
||||
c |= MCI_CPSM_LONGRSP;
|
||||
c |= MCI_CPSM_RESPONSE;
|
||||
break;
|
||||
}
|
||||
if (/*interrupt*/0)
|
||||
c |= MCI_CPSM_INTERRUPT;
|
||||
|
|
|
@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd,
|
|||
if (cmd->flags & MMC_RSP_BUSY)
|
||||
cmdat |= CMDAT_BUSY;
|
||||
|
||||
switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
|
||||
case MMC_RSP_SHORT | MMC_RSP_CRC:
|
||||
#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
|
||||
switch (RSP_TYPE(mmc_resp_type(cmd))) {
|
||||
case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */
|
||||
cmdat |= CMDAT_RESP_SHORT;
|
||||
break;
|
||||
case MMC_RSP_SHORT:
|
||||
case RSP_TYPE(MMC_RSP_R3):
|
||||
cmdat |= CMDAT_RESP_R3;
|
||||
break;
|
||||
case MMC_RSP_LONG | MMC_RSP_CRC:
|
||||
case RSP_TYPE(MMC_RSP_R2):
|
||||
cmdat |= CMDAT_RESP_R2;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -459,7 +459,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
|
|||
/*
|
||||
* Do we expect a reply?
|
||||
*/
|
||||
if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) {
|
||||
if (cmd->flags & MMC_RSP_PRESENT) {
|
||||
/*
|
||||
* Read back status.
|
||||
*/
|
||||
|
@ -476,10 +476,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
|
|||
cmd->error = MMC_ERR_BADCRC;
|
||||
/* All ok */
|
||||
else {
|
||||
if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT)
|
||||
wbsd_get_short_reply(host, cmd);
|
||||
else
|
||||
if (cmd->flags & MMC_RSP_136)
|
||||
wbsd_get_long_reply(host, cmd);
|
||||
else
|
||||
wbsd_get_short_reply(host, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,24 +21,35 @@ struct mmc_command {
|
|||
u32 arg;
|
||||
u32 resp[4];
|
||||
unsigned int flags; /* expected response type */
|
||||
#define MMC_RSP_NONE (0 << 0)
|
||||
#define MMC_RSP_SHORT (1 << 0)
|
||||
#define MMC_RSP_LONG (2 << 0)
|
||||
#define MMC_RSP_MASK (3 << 0)
|
||||
#define MMC_RSP_CRC (1 << 3) /* expect valid crc */
|
||||
#define MMC_RSP_BUSY (1 << 4) /* card may send busy */
|
||||
#define MMC_RSP_OPCODE (1 << 5) /* response contains opcode */
|
||||
#define MMC_RSP_PRESENT (1 << 0)
|
||||
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
|
||||
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
|
||||
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
|
||||
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
|
||||
#define MMC_CMD_MASK (3 << 5) /* command type */
|
||||
#define MMC_CMD_AC (0 << 5)
|
||||
#define MMC_CMD_ADTC (1 << 5)
|
||||
#define MMC_CMD_BC (2 << 5)
|
||||
#define MMC_CMD_BCR (3 << 5)
|
||||
|
||||
/*
|
||||
* These are the response types, and correspond to valid bit
|
||||
* patterns of the above flags. One additional valid pattern
|
||||
* is all zeros, which means we don't expect a response.
|
||||
*/
|
||||
#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE)
|
||||
#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
|
||||
#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC)
|
||||
#define MMC_RSP_R3 (MMC_RSP_SHORT)
|
||||
#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC)
|
||||
#define MMC_RSP_NONE (0)
|
||||
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
|
||||
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
|
||||
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
|
||||
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
|
||||
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC)
|
||||
|
||||
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
|
||||
|
||||
/*
|
||||
* These are the command types.
|
||||
*/
|
||||
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_TYPE)
|
||||
|
||||
unsigned int retries; /* max number of retries */
|
||||
unsigned int error; /* command error */
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
/* SD commands type argument response */
|
||||
/* class 8 */
|
||||
/* This is basically the same command as for MMC with some quirks. */
|
||||
#define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */
|
||||
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
|
||||
|
||||
/* Application commands */
|
||||
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user