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; }
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; }
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); }
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; }
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; }
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; }