示例#1
0
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
    unsigned int datactrl, timeout, irqmask;
    unsigned long long clks;
    void __iomem *base;
    int blksz_bits;

    DBG(host, "blksz %04x blks %04x flags %08x\n",
        data->blksz, data->blocks, data->flags);

    host->data = data;
    host->size = data->blksz;
    host->data_xfered = 0;

    mmci_init_sg(host, data);

    clks = (unsigned long long)data->timeout_ns * host->cclk;
    do_div(clks, 1000000000UL);

    timeout = data->timeout_clks + (unsigned int)clks;

    base = host->base;
    writel(timeout, base + MMCIDATATIMER);
    writel(host->size, base + MMCIDATALENGTH);

    blksz_bits = ffs(data->blksz) - 1;
    BUG_ON(1 << blksz_bits != data->blksz);

    datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
    if (data->flags & MMC_DATA_READ) {
        datactrl |= MCI_DPSM_DIRECTION;
        irqmask = MCI_RXFIFOHALFFULLMASK;

        /*
         * If we have less than a FIFOSIZE of bytes to transfer,
         * trigger a PIO interrupt as soon as any data is available.
         */
        if (host->size < MCI_FIFOSIZE)
            irqmask |= MCI_RXDATAAVLBLMASK;
    } else {
        /*
         * We don't actually need to include "FIFO empty" here
         * since its implicit in "FIFO half empty".
         */
        irqmask = MCI_TXFIFOHALFEMPTYMASK;
    }

    writel(datactrl, base + MMCIDATACTRL);
    writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
    writel(irqmask, base + MMCIMASK1);
}
示例#2
0
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
	unsigned int datactrl, timeout, irqmask;
	unsigned long long clks;
	void __iomem *base;

	DBG(host, "blksz %04x blks %04x flags %08x\n",
	    1 << data->blksz_bits, data->blocks, data->flags);

	host->data = data;
	host->size = data->blocks << data->blksz_bits;
	host->data_xfered = 0;

	mmci_init_sg(host, data);

	clks = (unsigned long long)data->timeout_ns * host->cclk;
	do_div(clks, 1000000000UL);

	timeout = data->timeout_clks + (unsigned int)clks;

	base = host->base;
	writel(timeout, base + MMCIDATATIMER);
	writel(host->size, base + MMCIDATALENGTH);

	datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
	if (data->flags & MMC_DATA_READ) {
		datactrl |= MCI_DPSM_DIRECTION;
		irqmask = MCI_RXFIFOHALFFULLMASK;
	} else {
		/*
		 * We don't actually need to include "FIFO empty" here
		 * since its implicit in "FIFO half empty".
		 */
		irqmask = MCI_TXFIFOHALFEMPTYMASK;
	}

	writel(datactrl, base + MMCIDATACTRL);
	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
	writel(irqmask, base + MMCIMASK1);
}
示例#3
0
文件: mmci.c 项目: Lyude/linux
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
	struct variant_data *variant = host->variant;
	unsigned int datactrl, timeout, irqmask;
	unsigned long long clks;
	void __iomem *base;
	int blksz_bits;

	dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
		data->blksz, data->blocks, data->flags);

	host->data = data;
	host->size = data->blksz * data->blocks;
	data->bytes_xfered = 0;

	clks = (unsigned long long)data->timeout_ns * host->cclk;
	do_div(clks, NSEC_PER_SEC);

	timeout = data->timeout_clks + (unsigned int)clks;

	base = host->base;
	writel(timeout, base + MMCIDATATIMER);
	writel(host->size, base + MMCIDATALENGTH);

	blksz_bits = ffs(data->blksz) - 1;
	BUG_ON(1 << blksz_bits != data->blksz);

	if (variant->blksz_datactrl16)
		datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
	else if (variant->blksz_datactrl4)
		datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
	else
		datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;

	if (data->flags & MMC_DATA_READ)
		datactrl |= MCI_DPSM_DIRECTION;

	if (host->mmc->card && mmc_card_sdio(host->mmc->card)) {
		u32 clk;

		datactrl |= variant->datactrl_mask_sdio;

		/*
		 * The ST Micro variant for SDIO small write transfers
		 * needs to have clock H/W flow control disabled,
		 * otherwise the transfer will not start. The threshold
		 * depends on the rate of MCLK.
		 */
		if (variant->st_sdio && data->flags & MMC_DATA_WRITE &&
		    (host->size < 8 ||
		     (host->size <= 8 && host->mclk > 50000000)))
			clk = host->clk_reg & ~variant->clkreg_enable;
		else
			clk = host->clk_reg | variant->clkreg_enable;

		mmci_write_clkreg(host, clk);
	}

	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
		datactrl |= variant->datactrl_mask_ddrmode;

	/*
	 * Attempt to use DMA operation mode, if this
	 * should fail, fall back to PIO mode
	 */
	if (!mmci_dma_start_data(host, datactrl))
		return;

	/* IRQ mode, map the SG list for CPU reading/writing */
	mmci_init_sg(host, data);

	if (data->flags & MMC_DATA_READ) {
		irqmask = MCI_RXFIFOHALFFULLMASK;

		/*
		 * If we have less than the fifo 'half-full' threshold to
		 * transfer, trigger a PIO interrupt as soon as any data
		 * is available.
		 */
		if (host->size < variant->fifohalfsize)
			irqmask |= MCI_RXDATAAVLBLMASK;
	} else {
		/*
		 * We don't actually need to include "FIFO empty" here
		 * since its implicit in "FIFO half empty".
		 */
		irqmask = MCI_TXFIFOHALFEMPTYMASK;
	}

	mmci_write_datactrlreg(host, datactrl);
	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
	mmci_set_mask1(host, irqmask);
}