static void msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) { unsigned int datactrl, timeout; unsigned long long clks; void __iomem *base = host->base; unsigned int pio_irqmask = 0; host->curr.data = data; host->curr.xfer_size = data->blksz * data->blocks; host->curr.xfer_remain = host->curr.xfer_size; host->curr.data_xfered = 0; host->curr.got_dataend = 0; host->curr.got_datablkend = 0; memset(&host->pio, 0, sizeof(host->pio)); clks = (unsigned long long)data->timeout_ns * host->clk_rate; do_div(clks, 1000000000UL); timeout = data->timeout_clks + (unsigned int)clks; writel(timeout, base + MMCIDATATIMER); writel(host->curr.xfer_size, base + MMCIDATALENGTH); datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); if (!msmsdcc_config_dma(host, data)) datactrl |= MCI_DPSM_DMAENABLE; else { host->pio.sg = data->sg; host->pio.sg_len = data->sg_len; host->pio.sg_off = 0; if (data->flags & MMC_DATA_READ) { pio_irqmask = MCI_RXFIFOHALFFULLMASK; if (host->curr.xfer_remain < MCI_FIFOSIZE) pio_irqmask |= MCI_RXDATAAVLBLMASK; } else pio_irqmask = MCI_TXFIFOHALFEMPTYMASK; } if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; writel(pio_irqmask, base + MMCIMASK1); writel(datactrl, base + MMCIDATACTRL); if (datactrl & MCI_DPSM_DMAENABLE) { host->dma.busy = 1; dsb(); msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); if (data->flags & MMC_DATA_WRITE) host->prog_scan = 1; } }
static void msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data, struct mmc_command *cmd, u32 c) { unsigned int datactrl, timeout; unsigned long long clks; void __iomem *base = host->base; unsigned int pio_irqmask = 0; host->curr.data = data; host->curr.xfer_size = data->blksz * data->blocks; host->curr.xfer_remain = host->curr.xfer_size; host->curr.data_xfered = 0; host->curr.got_dataend = 0; host->curr.got_datablkend = 0; memset(&host->pio, 0, sizeof(host->pio)); datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); if (!msmsdcc_config_dma(host, data)) datactrl |= MCI_DPSM_DMAENABLE; else { host->pio.sg = data->sg; host->pio.sg_len = data->sg_len; host->pio.sg_off = 0; if (data->flags & MMC_DATA_READ) { pio_irqmask = MCI_RXFIFOHALFFULLMASK; if (host->curr.xfer_remain < MCI_FIFOSIZE) pio_irqmask |= MCI_RXDATAAVLBLMASK; } else pio_irqmask = MCI_TXFIFOHALFEMPTYMASK; } if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; clks = (unsigned long long)data->timeout_ns * host->clk_rate; do_div(clks, 1000000000UL); timeout = data->timeout_clks + (unsigned int)clks*2 ; #if defined (CONFIG_MACH_ACER_A1) timeout *= 10; #endif if (datactrl & MCI_DPSM_DMAENABLE) { /* Save parameters for the exec function */ host->cmd_timeout = timeout; host->cmd_pio_irqmask = pio_irqmask; host->cmd_datactrl = datactrl; host->cmd_cmd = cmd; host->dma.hdr.exec_func = msmsdcc_dma_exec_func; host->dma.hdr.user = (void *)host; host->dma.busy = 1; if (cmd) { msmsdcc_start_command_deferred(host, cmd, &c); host->cmd_c = c; } dsb(); msm_dmov_enqueue_cmd_ext(host->dma.channel, &host->dma.hdr); if (data->flags & MMC_DATA_WRITE) host->prog_scan = 1; } else { writel(timeout, base + MMCIDATATIMER); writel(host->curr.xfer_size, base + MMCIDATALENGTH); writel(pio_irqmask, base + MMCIMASK1); msmsdcc_delay(host); /* Allow parms to be applied */ writel(datactrl, base + MMCIDATACTRL); if (cmd) { msmsdcc_delay(host); /* Delay between data/command */ /* Daisy-chain the command if requested */ msmsdcc_start_command(host, cmd, c); } } }