X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fmmc%2Fmvebu_mmc.c;h=3c7fb2130e041aef464b6b8ba090a54084b11446;hb=31f044bd91df58bed6bb8cfadfc187eedac1442e;hp=91a9be06e66df5b9ea3a38588d833e38dc67a40d;hpb=28d27b79e33dea24b0fb29cf7ff6e88dfb18f030;p=oweals%2Fu-boot.git diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index 91a9be06e6..3c7fb2130e 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -71,8 +72,8 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ushort xfertype = 0; ushort resp_indx = 0; - debug("cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", - cmd->cmdidx, cmd->resp_type, cmd->cmdarg); + debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", + DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg); debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME, cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE)); @@ -103,13 +104,9 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, DRIVER_NAME, hw_state, count, (get_timer(0) - (start))); } - /* Set up for a data transfer if we have one */ - if (data) { - int err = mvebu_mmc_setup_data(data); - - if (err) - return err; - } + /* Clear status */ + mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); + mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); resptype = SDIO_CMD_INDEX(cmd->cmdidx); @@ -135,6 +132,14 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, } if (data) { + int err = mvebu_mmc_setup_data(data); + + if (err) { + debug("%s: command DATA error :%x\n", + DRIVER_NAME, err); + return err; + } + resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16; xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN; if (data->flags & MMC_DATA_READ) { @@ -154,15 +159,9 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, /* Setting Xfer mode */ mvebu_mmc_write(SDIO_XFER_MODE, xfertype); - mvebu_mmc_write(SDIO_NOR_INTR_STATUS, ~SDIO_NOR_CARD_INT); - mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); - /* Sending command */ mvebu_mmc_write(SDIO_CMD, resptype); - mvebu_mmc_write(SDIO_NOR_INTR_EN, SDIO_POLL_MASK); - mvebu_mmc_write(SDIO_ERR_INTR_EN, SDIO_POLL_MASK); - start = get_timer(0); while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) { @@ -171,21 +170,21 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, DRIVER_NAME, cmd->cmdidx, mvebu_mmc_read(SDIO_ERR_INTR_STATUS)); if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & - (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) - return TIMEOUT; - return COMM_ERR; + (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) { + debug("%s: command READ timed out\n", + DRIVER_NAME); + return -ETIMEDOUT; + } + debug("%s: command READ error\n", DRIVER_NAME); + return -ECOMM; } if ((get_timer(0) - start) > TIMEOUT_DELAY) { debug("%s: command timed out\n", DRIVER_NAME); - return TIMEOUT; + return -ETIMEDOUT; } } - if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & - (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) - return TIMEOUT; - /* Handling response */ if (cmd->resp_type & MMC_RSP_136) { uint response[8]; @@ -218,6 +217,11 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, cmd->response[1] = ((response[0] & 0xfc00) >> 10); cmd->response[2] = 0; cmd->response[3] = 0; + } else { + cmd->response[0] = 0; + cmd->response[1] = 0; + cmd->response[2] = 0; + cmd->response[3] = 0; } debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type); @@ -227,6 +231,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, debug("[0x%x] ", cmd->response[3]); debug("\n"); + if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & + (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) + return -ETIMEDOUT; + return 0; } @@ -265,9 +273,8 @@ static void mvebu_mmc_set_clk(unsigned int clock) if (m > MVEBU_MMC_BASE_DIV_MAX) m = MVEBU_MMC_BASE_DIV_MAX; mvebu_mmc_write(SDIO_CLK_DIV, m & MVEBU_MMC_BASE_DIV_MAX); + debug("%s: clock (%d) div : %d\n", DRIVER_NAME, clock, m); } - - udelay(10*1000); } static void mvebu_mmc_set_bus(unsigned int bus) @@ -307,15 +314,16 @@ static void mvebu_mmc_set_bus(unsigned int bus) "high-speed" : ""); mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); - udelay(10*1000); } -static void mvebu_mmc_set_ios(struct mmc *mmc) +static int mvebu_mmc_set_ios(struct mmc *mmc) { debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, mmc->bus_width, mmc->clock); mvebu_mmc_set_bus(mmc->bus_width); mvebu_mmc_set_clk(mmc->clock); + + return 0; } /* @@ -369,7 +377,7 @@ static void mvebu_window_setup(void) static int mvebu_mmc_initialize(struct mmc *mmc) { - debug("%s: mvebu_mmc_initialize", DRIVER_NAME); + debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME); /* * Setting host parameters @@ -398,8 +406,6 @@ static int mvebu_mmc_initialize(struct mmc *mmc) /* SW reset */ mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); - udelay(10*1000); - return 0; } @@ -415,7 +421,7 @@ static struct mmc_config mvebu_mmc_cfg = { .f_min = MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX, .f_max = MVEBU_MMC_CLOCKRATE_MAX, .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC | + .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz, .part_type = PART_TYPE_DOS, .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,