// SPDX-License-Identifier: GPL-2.0 /* * Driver for the MMC / SD / SDIO IP found in: * * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs * * Copyright (C) 2015-19 Renesas Electronics Corporation * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang * Copyright (C) 2017 Horms Solutions, Simon Horman * Copyright (C) 2011 Guennadi Liakhovetski * Copyright (C) 2007 Ian Molton * Copyright (C) 2004 Ian Molton * * This driver draws mainly on scattered spec sheets, Reverse engineering * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit * support). (Further 4 bit support from a later datasheet). * * TODO: * Investigate using a workqueue for PIO transfers * Eliminate FIXMEs * Better Power management * Handle MMC errors better * double buffer support *
*/
/* * is request already finished? Since we use a non-blocking * cancel_delayed_work(), it can happen, that a .set_ios() call preempts * us, so, have to check for IS_ERR(host->mrq)
*/ if (IS_ERR_OR_NULL(mrq) ||
time_is_after_jiffies(host->last_req_ts +
msecs_to_jiffies(CMDREQ_TIMEOUT))) {
spin_unlock_irqrestore(&host->lock, flags); return;
}
dev_warn(&host->pdev->dev, "timeout waiting for hardware interrupt (CMD%u)\n",
mrq->cmd->opcode);
/* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
host->mrq = ERR_PTR(-EBUSY);
host->cmd = NULL;
host->data = NULL;
spin_unlock_irqrestore(&host->lock, flags);
tmio_mmc_reset(host, true);
/* Ready for new calls */
host->mrq = NULL;
mmc_request_done(host->mmc, mrq);
}
/* These are the bitmasks the tmio chip requires to implement the MMC response
* types. Note that R1 and R6 are the same in this scheme. */ #define APP_CMD 0x0040 #define RESP_NONE 0x0300 #define RESP_R1 0x0400 #define RESP_R1B 0x0500 #define RESP_R2 0x0600 #define RESP_R3 0x0700 #define DATA_PRESENT 0x0800 #define TRANSFER_READ 0x1000 #define TRANSFER_MULTI 0x2000 #define SECURITY_CMD 0x4000 #define NO_CMD12_ISSUE 0x4000 /* TMIO_MMC_HAVE_CMD12_CTRL */
staticint tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
{ struct mmc_data *data = host->data; int c = cmd->opcode;
switch (mmc_resp_type(cmd)) { case MMC_RSP_NONE: c |= RESP_NONE; break; case MMC_RSP_R1:
c |= RESP_R1; break; case MMC_RSP_R1B: c |= RESP_R1B; break; case MMC_RSP_R2: c |= RESP_R2; break; case MMC_RSP_R3: c |= RESP_R3; break; default:
pr_debug("Unknown response type %d\n", mmc_resp_type(cmd)); return -EINVAL;
}
host->cmd = cmd;
/* FIXME - this seems to be ok commented out but the spec suggest this bit * should be set when issuing app commands. * if(cmd->flags & MMC_FLAG_ACMD) * c |= APP_CMD;
*/ if (data) {
c |= DATA_PRESENT; if (data->blocks > 1) {
sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, TMIO_STOP_SEC);
c |= TRANSFER_MULTI;
/* * Disable auto CMD12 at IO_RW_EXTENDED and * SET_BLOCK_COUNT when doing multiple block transfer
*/ if ((host->pdata->flags & TMIO_MMC_HAVE_CMD12_CTRL) &&
(cmd->opcode == SD_IO_RW_EXTENDED || host->mrq->sbc))
c |= NO_CMD12_ISSUE;
} if (data->flags & MMC_DATA_READ)
c |= TRANSFER_READ;
}
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_CMD);
/* Fire off the command */
sd_ctrl_write32_as_16_and_16(host, CTL_ARG_REG, cmd->arg);
sd_ctrl_write16(host, CTL_SD_CMD, c);
/* if count was even number */ if (!(count & 0x1)) return;
/* if count was odd number */
buf8 = (u8 *)(buf + (count >> 1));
/* * FIXME * * driver and this function are assuming that * it is used as little endian
*/ if (is_read)
*buf8 = sd_ctrl_read16(host, CTL_SD_DATA_PORT) & 0xff; else
sd_ctrl_write16(host, CTL_SD_DATA_PORT, *buf8);
}
/* * This chip always returns (at least?) as much data as you ask for. * I'm unsure what happens if you ask for less than a block. This should be * looked into to ensure that a funny length read doesn't hose the controller.
*/ staticvoid tmio_mmc_pio_irq(struct tmio_mmc_host *host)
{ struct mmc_data *data = host->data; void *sg_virt; unsignedshort *buf; unsignedint count;
if (host->dma_on) {
pr_err("PIO IRQ in DMA mode!\n"); return;
} elseif (!data) {
pr_debug("Spurious PIO IRQ\n"); return;
}
/* needs to be called with host->lock held */ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
{ struct mmc_data *data = host->data; struct mmc_command *stop;
host->data = NULL;
if (!data) {
dev_warn(&host->pdev->dev, "Spurious data end IRQ\n"); return;
}
stop = data->stop;
/* FIXME - return correct transfer count on errors */ if (!data->error)
data->bytes_xfered = data->blocks * data->blksz; else
data->bytes_xfered = 0;
pr_debug("Completed data request\n");
/* * FIXME: other drivers allow an optional stop command of any given type * which we dont do, as the chip can auto generate them. * Perhaps we can be smarter about when to use auto CMD12 and * only issue the auto request when we know this is the desired * stop command, allowing fallback to the stop command the * upper layers expect. For now, we do what works.
*/
if (stop && !host->mrq->sbc) { if (stop->opcode != MMC_STOP_TRANSMISSION || stop->arg)
dev_err(&host->pdev->dev, "unsupported stop: CMD%u,0x%x. We did CMD12,0\n",
stop->opcode, stop->arg);
/* fill in response from auto CMD12 */
stop->resp[0] = sd_ctrl_read16_and_16_as_32(host, CTL_RESPONSE);
if (stat & TMIO_STAT_DATATIMEOUT)
data->error = -ETIMEDOUT; elseif (stat & TMIO_STAT_CRCFAIL || stat & TMIO_STAT_STOPBIT_ERR ||
stat & TMIO_STAT_TXUNDERRUN)
data->error = -EILSEQ; if (host->dma_on && (data->flags & MMC_DATA_WRITE)) {
u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS); bool done = false;
/* * Has all data been written out yet? Testing on SuperH showed, * that in most cases the first interrupt comes already with the * BUSY status bit clear, but on some operations, like mount or * in the beginning of a write / sync / umount, there is one * DATAEND interrupt with the BUSY bit set, in this cases * waiting for one more interrupt fixes the problem.
*/ if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) { if (status & TMIO_STAT_SCLKDIVEN)
done = true;
} else { if (!(status & TMIO_STAT_CMD_BUSY))
done = true;
}
staticvoid tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsignedint stat)
{ struct mmc_command *cmd = host->cmd; int i, addr;
spin_lock(&host->lock);
if (!host->cmd) {
pr_debug("Spurious CMD irq\n"); goto out;
}
/* This controller is sicker than the PXA one. Not only do we need to * drop the top 8 bits of the first response word, we also need to * modify the order of the response for short response command types.
*/
for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
cmd->resp[i] = sd_ctrl_read16_and_16_as_32(host, addr);
if (stat & TMIO_STAT_CMDTIMEOUT)
cmd->error = -ETIMEDOUT; elseif ((stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) ||
stat & TMIO_STAT_STOPBIT_ERR ||
stat & TMIO_STAT_CMD_IDX_ERR)
cmd->error = -EILSEQ;
/* If there is data to handle we enable data IRQs here, and * we will ultimatley finish the request in the data_end handler. * If theres no data or we encountered an error, finish now.
*/ if (host->data && (!cmd->error || cmd->error == -EILSEQ)) { if (host->data->flags & MMC_DATA_READ) { if (!host->dma_on) {
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP);
} else {
tmio_mmc_disable_mmc_irqs(host,
TMIO_MASK_READOP);
queue_work(system_bh_wq, &host->dma_issue);
}
} else { if (!host->dma_on) {
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
} else {
tmio_mmc_disable_mmc_irqs(host,
TMIO_MASK_WRITEOP);
queue_work(system_bh_wq, &host->dma_issue);
}
}
} else {
schedule_work(&host->done);
}
out:
spin_unlock(&host->lock);
}
staticbool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host, int ireg, int status)
{ struct mmc_host *mmc = host->mmc;
mrq = host->mrq; if (IS_ERR_OR_NULL(mrq)) {
spin_unlock_irqrestore(&host->lock, flags); return;
}
/* If not SET_BLOCK_COUNT, clear old data */ if (host->cmd != mrq->sbc) {
host->cmd = NULL;
host->data = NULL;
host->mrq = NULL;
}
cancel_delayed_work(&host->delayed_reset_work);
spin_unlock_irqrestore(&host->lock, flags);
if (mrq->cmd->error || (mrq->data && mrq->data->error)) {
tmio_mmc_ack_mmc_irqs(host, TMIO_MASK_IRQ); /* Clear all */
tmio_mmc_abort_dma(host);
}
/* Error means retune, but executed command was still successful */ if (host->check_retune && host->check_retune(host, mrq))
mmc_retune_needed(host->mmc);
/* If SET_BLOCK_COUNT, continue with main command */ if (host->mrq && !mrq->cmd->error) {
tmio_process_mrq(host, mrq); return;
}
if (host->fixup_request)
host->fixup_request(host, mrq);
staticvoid tmio_mmc_power_on(struct tmio_mmc_host *host, unsignedshort vdd)
{ struct mmc_host *mmc = host->mmc; int ret = 0;
/* .set_ios() is returning void, so, no chance to report an error */
if (!IS_ERR(mmc->supply.vmmc)) {
ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); /* * Attention: empiric value. With a b43 WiFi SDIO card this * delay proved necessary for reliable card-insertion probing. * 100us were not enough. Is this the same 140us delay, as in * tmio_mmc_set_ios()?
*/
usleep_range(200, 300);
} /* * It seems, VccQ should be switched on after Vcc, this is also what the * omap_hsmmc.c driver does.
*/ if (!ret) {
ret = mmc_regulator_enable_vqmmc(mmc);
usleep_range(200, 300);
}
if (ret < 0)
dev_dbg(&host->pdev->dev, "Regulators failed to power up: %d\n",
ret);
}
/* Set MMC clock / power. * Note: This controller uses a simple divider scheme therefore it cannot * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as * MMC wont run that fast, it has to be clocked at 12MHz which is the next * slowest setting.
*/ staticvoid tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{ struct tmio_mmc_host *host = mmc_priv(mmc); struct device *dev = &host->pdev->dev; unsignedlong flags;
mutex_lock(&host->ios_lock);
spin_lock_irqsave(&host->lock, flags); if (host->mrq) { if (IS_ERR(host->mrq)) {
dev_dbg(dev, "%s.%d: concurrent .set_ios(), clk %u, mode %u\n",
current->comm, task_pid_nr(current),
ios->clock, ios->power_mode);
host->mrq = ERR_PTR(-EINTR);
} else {
dev_dbg(dev, "%s.%d: CMD%u active since %lu, now %lu!\n",
current->comm, task_pid_nr(current),
host->mrq->cmd->opcode, host->last_req_ts,
jiffies);
}
spin_unlock_irqrestore(&host->lock, flags);
mutex_unlock(&host->ios_lock); return;
}
/* Disallow new mrqs and work handlers to run */
host->mrq = ERR_PTR(-EBUSY);
spin_unlock_irqrestore(&host->lock, flags);
switch (ios->power_mode) { case MMC_POWER_OFF:
tmio_mmc_power_off(host); /* For R-Car Gen2+, we need to reset SDHI specific SCC */ if (host->pdata->flags & TMIO_MMC_MIN_RCAR2)
tmio_mmc_reset(host, false);
host->set_clock(host, 0); break; case MMC_POWER_UP:
tmio_mmc_power_on(host, ios->vdd);
host->set_clock(host, ios->clock);
tmio_mmc_set_bus_width(host, ios->bus_width); break; case MMC_POWER_ON:
host->set_clock(host, ios->clock);
tmio_mmc_set_bus_width(host, ios->bus_width); break;
}
if (host->pdata->flags & TMIO_MMC_USE_BUSY_TIMEOUT)
tmio_mmc_max_busy_timeout(host);
/* Let things settle. delay taken from winCE driver */
usleep_range(140, 200); if (PTR_ERR(host->mrq) == -EINTR)
dev_dbg(&host->pdev->dev, "%s.%d: IOS interrupted: clk %u, mode %u",
current->comm, task_pid_nr(current),
ios->clock, ios->power_mode);
/* Ready for new mrqs */
host->mrq = NULL;
host->clk_cache = ios->clock;
/* * DEPRECATED: * For new platforms, please use "disable-wp" instead of * "toshiba,mmc-wrprotect-disable"
*/ if (of_property_read_bool(np, "toshiba,mmc-wrprotect-disable"))
mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
}
/* * Check the sanity of mmc->f_min to prevent host->set_clock() from * looping forever...
*/ if (mmc->f_min == 0) return -EINVAL;
if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT))
_host->write16_hook = NULL;
if (pdata->flags & TMIO_MMC_USE_BUSY_TIMEOUT && !_host->get_timeout_cycles)
_host->get_timeout_cycles = tmio_mmc_get_timeout_cycles;
ret = tmio_mmc_init_ocr(_host); if (ret < 0) return ret;
/* * Look for a card detect GPIO, if it fails with anything * else than a probe deferral, just live without it.
*/
ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0); if (ret == -EPROBE_DEFER) return ret;
if (mmc_host_can_gpio_ro(mmc))
_host->ops.get_ro = mmc_gpio_get_ro;
if (mmc_host_can_gpio_cd(mmc))
_host->ops.get_cd = mmc_gpio_get_cd;
/* must be set before tmio_mmc_reset() */
_host->native_hotplug = !(mmc_host_can_gpio_cd(mmc) ||
mmc->caps & MMC_CAP_NEEDS_POLL ||
!mmc_card_is_removable(mmc));
/* * While using internal tmio hardware logic for card detection, we need * to ensure it stays powered for it to work.
*/ if (_host->native_hotplug)
pm_runtime_get_noresume(&pdev->dev);
_host->sdio_irq_enabled = false; if (pdata->flags & TMIO_MMC_SDIO_IRQ)
_host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
if (!_host->sdcard_irq_mask_all)
_host->sdcard_irq_mask_all = TMIO_MASK_ALL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.