static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { u32 status; int ret = 0; u16 reg = 0; if (data) { ret = sdh_setup_data(mmc, data); if (ret) return ret; } ret = sdh_send_cmd(mmc, cmd); if (ret) { bfin_write_SDH_COMMAND(0); bfin_write_DMA_CONFIG(0); bfin_write_SDH_DATA_CTL(0); SSYNC(); printf("sending CMD%d failed\n", cmd->cmdidx); return ret; } if (data) { do { udelay(1); status = bfin_read_SDH_STATUS(); } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN))); if (status & DAT_TIME_OUT) { reg |= DAT_TIMEOUT_STAT; ret |= TIMEOUT; } else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) { reg |= DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT; ret |= COMM_ERR; } else reg |= DAT_BLK_END_STAT | DAT_END_STAT; bfin_write_SDH_STATUS_CLR(reg); bfin_write_DMA_CONFIG(0); bfin_write_SDH_DATA_CTL(0); SSYNC(); if (ret) { printf("tranfering data failed\n"); return ret; } } return 0; }
static int sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) { unsigned int sdh_cmd; unsigned int status; int cmd = mmc_cmd->cmdidx; int flags = mmc_cmd->resp_type; int arg = mmc_cmd->cmdarg; int ret = 0; sdh_cmd = 0; sdh_cmd |= cmd; if (flags & MMC_RSP_PRESENT) sdh_cmd |= CMD_RSP; if (flags & MMC_RSP_136) sdh_cmd |= CMD_L_RSP; bfin_write_SDH_ARGUMENT(arg); bfin_write_SDH_COMMAND(sdh_cmd | CMD_E); /* wait for a while */ do { udelay(1); status = bfin_read_SDH_STATUS(); } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL))); if (flags & MMC_RSP_PRESENT) { mmc_cmd->response[0] = bfin_read_SDH_RESPONSE0(); if (flags & MMC_RSP_136) { mmc_cmd->response[1] = bfin_read_SDH_RESPONSE1(); mmc_cmd->response[2] = bfin_read_SDH_RESPONSE2(); mmc_cmd->response[3] = bfin_read_SDH_RESPONSE3(); } } if (status & CMD_TIME_OUT) ret |= TIMEOUT; else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) ret |= COMM_ERR; bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); return ret; }
static int mmc_cmd(unsigned long cmd, unsigned long arg, void *resp, unsigned long flags) { unsigned int sdh_cmd; unsigned int status; int ret = 0; sdh_cmd = 0; unsigned long *response = resp; sdh_cmd |= cmd; if (flags & MMC_RSP_PRESENT) sdh_cmd |= CMD_RSP; if (flags & MMC_RSP_136) sdh_cmd |= CMD_L_RSP; bfin_write_SDH_ARGUMENT(arg); bfin_write_SDH_COMMAND(sdh_cmd | CMD_E); /* wait for a while */ do { udelay(1); status = bfin_read_SDH_STATUS(); } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL))); if (flags & MMC_RSP_PRESENT) { response[0] = bfin_read_SDH_RESPONSE0(); if (flags & MMC_RSP_136) { response[1] = bfin_read_SDH_RESPONSE1(); response[2] = bfin_read_SDH_RESPONSE2(); response[3] = bfin_read_SDH_RESPONSE3(); } } if (status & CMD_TIME_OUT) { printf("CMD%d timeout\n", (int)cmd); ret |= -ETIMEDOUT; } else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) { printf("CMD%d CRC failure\n", (int)cmd); ret |= -EILSEQ; } bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); return ret; }
static int sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) { unsigned int status, timeout; int cmd = mmc_cmd->cmdidx; int flags = mmc_cmd->resp_type; int arg = mmc_cmd->cmdarg; int ret; u16 sdh_cmd; sdh_cmd = cmd | CMD_E; if (flags & MMC_RSP_PRESENT) sdh_cmd |= CMD_RSP; if (flags & MMC_RSP_136) sdh_cmd |= CMD_L_RSP; #ifdef RSI_BLKSZ sdh_cmd |= CMD_DATA0_BUSY; #endif bfin_write_SDH_ARGUMENT(arg); bfin_write_SDH_COMMAND(sdh_cmd); /* wait for a while */ timeout = 0; do { if (++timeout > 1000000) { status = CMD_TIME_OUT; break; } udelay(1); status = bfin_read_SDH_STATUS(); } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | CMD_CRC_FAIL))); if (flags & MMC_RSP_PRESENT) { mmc_cmd->response[0] = bfin_read_SDH_RESPONSE0(); if (flags & MMC_RSP_136) { mmc_cmd->response[1] = bfin_read_SDH_RESPONSE1(); mmc_cmd->response[2] = bfin_read_SDH_RESPONSE2(); mmc_cmd->response[3] = bfin_read_SDH_RESPONSE3(); } } if (status & CMD_TIME_OUT) ret = TIMEOUT; else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) ret = COMM_ERR; else ret = 0; bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); #ifdef RSI_BLKSZ /* wait till card ready */ while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY)) continue; bfin_write_RSI_ESTAT(SD_CARD_READY); #endif return ret; }