Exemplo n.º 1
0
static int dwmci_prepare_data_pio(struct dwmci_host *host,
		struct mci_data *data)
{
	unsigned long ctrl;

	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
	dwmci_writel(host, DWMCI_RINTSTS,
			DWMCI_INTMSK_TXDR | DWMCI_INTMSK_RXDR);

	ctrl = dwmci_readl(host, DWMCI_INTMASK);
	ctrl |= DWMCI_INTMSK_TXDR | DWMCI_INTMSK_RXDR;
	dwmci_writel(host, DWMCI_INTMASK, ctrl);

	ctrl = dwmci_readl(host, DWMCI_CTRL);
	ctrl &= ~(DWMCI_IDMAC_EN | DWMCI_DMA_EN);
	dwmci_writel(host, DWMCI_CTRL, ctrl);

	dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);

	dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);
	dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
	dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);

	return 0;
}
Exemplo n.º 2
0
static int dwmci_init(struct mmc *mmc)
{
	struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
	u32 fifo_size, fifoth_val;

	dwmci_writel(host, DWMCI_PWREN, 1);

	if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
		debug("%s[%d] Fail-reset!!\n",__func__,__LINE__);
		return -1;
	}

	dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
	dwmci_writel(host, DWMCI_INTMASK, 0);

	dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);

	dwmci_writel(host, DWMCI_IDINTEN, 0);
	dwmci_writel(host, DWMCI_BMOD, 1);

	fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
	if (host->fifoth_val)
		fifoth_val = host->fifoth_val;
	else
		fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
			TX_WMARK(fifo_size/2);
	dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);

	dwmci_writel(host, DWMCI_CLKENA, 0);
	dwmci_writel(host, DWMCI_CLKSRC, 0);

	return 0;
}
Exemplo n.º 3
0
static void dwmci_prepare_data(struct dwmci_host *host,
		struct mmc_data *data)
{
	unsigned long ctrl;
	unsigned int i = 0, flags, cnt, blk_cnt;
	ulong data_start, data_end, start_addr;
	ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data->blocks);


	blk_cnt = data->blocks;

	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);

	data_start = (ulong)cur_idmac;
	dwmci_writel(host, DWMCI_DBADDR, (unsigned int)cur_idmac);

	if (data->flags == MMC_DATA_READ)
		start_addr = (unsigned int)data->dest;
	else
		start_addr = (unsigned int)data->src;

	do {
		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
		if (blk_cnt <= 8) {
			flags |= DWMCI_IDMAC_LD;
			cnt = data->blocksize * blk_cnt;
		} else
			cnt = data->blocksize * 8;

		dwmci_set_idma_desc(cur_idmac, flags, cnt,
				start_addr + (i * PAGE_SIZE));

		if(blk_cnt < 8)
			break;
		blk_cnt -= 8;
		cur_idmac++;
		i++;
	} while(1);

	data_end = (ulong)cur_idmac;
	flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);

	ctrl = dwmci_readl(host, DWMCI_CTRL);
	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
	dwmci_writel(host, DWMCI_CTRL, ctrl);

	ctrl = dwmci_readl(host, DWMCI_BMOD);
	ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN;
	dwmci_writel(host, DWMCI_BMOD, ctrl);

	dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
	dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
}
Exemplo n.º 4
0
static int dwmci_init(struct mci_host *mci, struct device_d *dev)
{
	struct dwmci_host *host = to_dwmci_host(mci);
	uint32_t fifo_size;

	dwmci_writel(host, DWMCI_PWREN, host->pwren_value);

	if (dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
		dev_err(host->dev, "reset failed\n");
		return -EIO;
	}

	dwmci_writel(host, DWMCI_RINTSTS, 0xffffffff);
	dwmci_writel(host, DWMCI_INTMASK, 0);

	dwmci_writel(host, DWMCI_TMOUT, 0xffffffff);

	dwmci_writel(host, DWMCI_IDINTEN, 0);
	dwmci_writel(host, DWMCI_BMOD, 1);

	fifo_size = dwmci_readl(host, DWMCI_FIFOTH);

	/*
	 * Use reset default of the rx_wmark field to determine the
	 * fifo depth.
	 */
	fifo_size = DWMCI_FIFOTH_FIFO_DEPTH(fifo_size);
	host->fifo_size_bytes = fifo_size * 4;

	/*
	 * If fifo-depth property is set, use this value
	 */
	if (!of_property_read_u32(host->dev->device_node,
		    "fifo-depth", &fifo_size)) {
		host->fifo_size_bytes = fifo_size;
		dev_dbg(host->dev, "Using fifo-depth=%u\n",
		    host->fifo_size_bytes);
	}

	host->fifoth_val = DWMCI_FIFOTH_MSIZE(0x2) |
		DWMCI_FIFOTH_RX_WMARK(fifo_size / 2 - 1) |
		DWMCI_FIFOTH_TX_WMARK(fifo_size / 2);

	dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);

	dwmci_writel(host, DWMCI_CLKENA, 0);
	dwmci_writel(host, DWMCI_CLKSRC, 0);

	return 0;
}
Exemplo n.º 5
0
static int dwmci_init(struct mci_host *mci, struct device_d *dev)
{
	struct dwmci_host *host = to_dwmci_host(mci);
	uint32_t fifo_size, fifoth_val;

	dwmci_writel(host, DWMCI_PWREN, 1);

	if (dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
		dev_err(host->dev, "reset failed\n");
		return -EIO;
	}

	dwmci_writel(host, DWMCI_RINTSTS, 0xffffffff);
	dwmci_writel(host, DWMCI_INTMASK, 0);

	dwmci_writel(host, DWMCI_TMOUT, 0xffffffff);

	dwmci_writel(host, DWMCI_IDINTEN, 0);
	dwmci_writel(host, DWMCI_BMOD, 1);

	fifo_size = dwmci_readl(host, DWMCI_FIFOTH);

	/*
	 * Use reset default of the rx_wmark field to determine the
	 * fifo depth.
	 */
	fifo_size = DWMCI_FIFOTH_FIFO_DEPTH(fifo_size);
	host->fifo_size_bytes = fifo_size * 4;

	fifoth_val = DWMCI_FIFOTH_MSIZE(0x2) |
		DWMCI_FIFOTH_RX_WMARK(fifo_size / 2 - 1) |
		DWMCI_FIFOTH_TX_WMARK(fifo_size / 2);

	dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);

	dwmci_writel(host, DWMCI_CLKENA, 0);
	dwmci_writel(host, DWMCI_CLKSRC, 0);

	return 0;
}
Exemplo n.º 6
0
static int dwmci_prepare_data_dma(struct dwmci_host *host,
		struct mci_data *data)
{
	unsigned long ctrl;
	unsigned int i = 0, flags, cnt, blk_cnt;
	unsigned long data_start, start_addr;
	struct dwmci_idmac *desc = host->idmac;

	blk_cnt = data->blocks;

	if (blk_cnt > DW_MMC_NUM_IDMACS)
		return -EINVAL;

	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);

	data_start = (uint32_t)desc;
	dwmci_writel(host, DWMCI_DBADDR, (uint32_t)desc);

	if (data->flags & MMC_DATA_READ)
		start_addr = (uint32_t)data->dest;
	else
		start_addr = (uint32_t)data->src;

	do {
		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH;
		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;

		if (blk_cnt <= 8) {
			flags |= DWMCI_IDMAC_LD;
			cnt = data->blocksize * blk_cnt;
		} else {
			cnt = data->blocksize * 8;
		}

		desc->flags = flags;
		desc->cnt = cnt;
		desc->addr = start_addr + (i * PAGE_SIZE);
		desc->next_addr = (uint32_t)(desc + 1);

		dev_dbg(host->dev, "desc@ 0x%p 0x%08x 0x%08x 0x%08x 0x%08x\n",
				desc, flags, cnt, desc->addr, desc->next_addr);
		if (blk_cnt < 8)
			break;

		blk_cnt -= 8;
		desc++;
		i++;
	} while (1);

	ctrl = dwmci_readl(host, DWMCI_CTRL);
	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
	dwmci_writel(host, DWMCI_CTRL, ctrl);

	ctrl = dwmci_readl(host, DWMCI_BMOD);
	ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN;
	dwmci_writel(host, DWMCI_BMOD, ctrl);

	dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
	dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);

	return 0;
}