Source
x
static void idma64_chan_start(struct idma64 *idma64, struct idma64_chan *idma64c)
/*
* Core driver for the Intel integrated DMA 64-bit
*
* Copyright (C) 2015 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* Platform driver name */
/* For now we support only two channels */
/* ---------------------------------------------------------------------- */
static struct device *chan2dev(struct dma_chan *chan)
{
return &chan->dev->device;
}
/* ---------------------------------------------------------------------- */
static void idma64_off(struct idma64 *idma64)
{
unsigned short count = 100;
dma_writel(idma64, CFG, 0);
channel_clear_bit(idma64, MASK(XFER), idma64->all_chan_mask);
channel_clear_bit(idma64, MASK(BLOCK), idma64->all_chan_mask);
channel_clear_bit(idma64, MASK(SRC_TRAN), idma64->all_chan_mask);
channel_clear_bit(idma64, MASK(DST_TRAN), idma64->all_chan_mask);
channel_clear_bit(idma64, MASK(ERROR), idma64->all_chan_mask);
do {
cpu_relax();
} while (dma_readl(idma64, CFG) & IDMA64_CFG_DMA_EN && --count);
}
static void idma64_on(struct idma64 *idma64)
{
dma_writel(idma64, CFG, IDMA64_CFG_DMA_EN);
}
/* ---------------------------------------------------------------------- */
static void idma64_chan_init(struct idma64 *idma64, struct idma64_chan *idma64c)
{
u32 cfghi = IDMA64C_CFGH_SRC_PER(1) | IDMA64C_CFGH_DST_PER(0);
u32 cfglo = 0;
/* Set default burst alignment */
cfglo |= IDMA64C_CFGL_DST_BURST_ALIGN | IDMA64C_CFGL_SRC_BURST_ALIGN;
channel_writel(idma64c, CFG_LO, cfglo);
channel_writel(idma64c, CFG_HI, cfghi);
/* Enable interrupts */
channel_set_bit(idma64, MASK(XFER), idma64c->mask);
channel_set_bit(idma64, MASK(ERROR), idma64c->mask);
/*
* Enforce the controller to be turned on.
*
* The iDMA is turned off in ->probe() and looses context during system
* suspend / resume cycle. That's why we have to enable it each time we
* use it.
*/
idma64_on(idma64);
}
static void idma64_chan_stop(struct idma64 *idma64, struct idma64_chan *idma64c)
{
channel_clear_bit(idma64, CH_EN, idma64c->mask);
}