Exemplo n.º 1
0
static int mmp_tdma_config_chan(struct mmp_tdma_chan *tdmac)
{
	unsigned int tdcr;

	mmp_tdma_disable_chan(tdmac);

	if (tdmac->dir == DMA_MEM_TO_DEV)
		tdcr = TDCR_DSTDIR_ADDR_HOLD | TDCR_SRCDIR_ADDR_INC;
	else if (tdmac->dir == DMA_DEV_TO_MEM)
		tdcr = TDCR_SRCDIR_ADDR_HOLD | TDCR_DSTDIR_ADDR_INC;

	if (tdmac->type == MMP_AUD_TDMA) {
		tdcr |= TDCR_PACKMOD;

		switch (tdmac->burst_sz) {
		case 4:
			tdcr |= TDCR_BURSTSZ_4B;
			break;
		case 8:
			tdcr |= TDCR_BURSTSZ_8B;
			break;
		case 16:
			tdcr |= TDCR_BURSTSZ_16B;
			break;
		case 32:
			tdcr |= TDCR_BURSTSZ_32B;
			break;
		case 64:
			tdcr |= TDCR_BURSTSZ_64B;
			break;
		case 128:
			tdcr |= TDCR_BURSTSZ_128B;
			break;
		default:
			dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n");
			return -EINVAL;
		}

		switch (tdmac->buswidth) {
		case DMA_SLAVE_BUSWIDTH_1_BYTE:
			tdcr |= TDCR_SSZ_8_BITS;
			break;
		case DMA_SLAVE_BUSWIDTH_2_BYTES:
			tdcr |= TDCR_SSZ_16_BITS;
			break;
		case DMA_SLAVE_BUSWIDTH_4_BYTES:
			tdcr |= TDCR_SSZ_32_BITS;
			break;
		default:
			dev_err(tdmac->dev, "mmp_tdma: unknown bus size.\n");
			return -EINVAL;
		}
	} else if (tdmac->type == PXA910_SQU) {
		tdcr |= TDCR_BURSTSZ_SQU_32B;
		tdcr |= TDCR_SSPMOD;
	}

	writel(tdcr, tdmac->reg_base + TDCR);
	return 0;
}
Exemplo n.º 2
0
static int mmp_tdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
		unsigned long arg)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
	struct dma_slave_config *dmaengine_cfg = (void *)arg;
	int ret = 0;

	switch (cmd) {
	case DMA_TERMINATE_ALL:
		mmp_tdma_disable_chan(tdmac);
		break;
	case DMA_PAUSE:
		mmp_tdma_pause_chan(tdmac);
		break;
	case DMA_RESUME:
		mmp_tdma_resume_chan(tdmac);
		break;
	case DMA_SLAVE_CONFIG:
		if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
			tdmac->dev_addr = dmaengine_cfg->src_addr;
			tdmac->burst_sz = dmaengine_cfg->src_maxburst;
			tdmac->buswidth = dmaengine_cfg->src_addr_width;
		} else {
			tdmac->dev_addr = dmaengine_cfg->dst_addr;
			tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
			tdmac->buswidth = dmaengine_cfg->dst_addr_width;
		}
		tdmac->dir = dmaengine_cfg->direction;
		return mmp_tdma_config_chan(tdmac);
	default:
		ret = -ENOSYS;
	}

	return ret;
}
Exemplo n.º 3
0
static int mmp_tdma_terminate_all(struct dma_chan *chan)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);

	mmp_tdma_disable_chan(chan);
	/* disable interrupt */
	mmp_tdma_enable_irq(tdmac, false);

	return 0;
}