dw_dmac: autoconfigure block_size or use platform data
The maximum block size is a configurable parameter for the chip. So, driver will try to get it from the encoded component parameters. Otherwise it will come from the platform data. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
This commit is contained in:
Родитель
482c67ea7b
Коммит
4a63a8b3e8
|
@ -78,6 +78,7 @@ struct dw_dma_platform_data dmac_plat_data = {
|
|||
.nr_channels = 8,
|
||||
.chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
|
||||
.chan_priority = CHAN_PRIORITY_DESCENDING,
|
||||
.block_size = 4095U,
|
||||
};
|
||||
|
||||
void __init spear13xx_l2x0_init(void)
|
||||
|
|
|
@ -605,6 +605,7 @@ static void __init genclk_init_parent(struct clk *clk)
|
|||
|
||||
static struct dw_dma_platform_data dw_dmac0_data = {
|
||||
.nr_channels = 3,
|
||||
.block_size = 4095U,
|
||||
};
|
||||
|
||||
static struct resource dw_dmac0_resource[] = {
|
||||
|
|
|
@ -55,16 +55,6 @@
|
|||
| DWC_CTLL_SMS(_sms)); \
|
||||
})
|
||||
|
||||
/*
|
||||
* This is configuration-dependent and usually a funny size like 4095.
|
||||
*
|
||||
* Note that this is a transfer count, i.e. if we transfer 32-bit
|
||||
* words, we can do 16380 bytes per descriptor.
|
||||
*
|
||||
* This parameter is also system-specific.
|
||||
*/
|
||||
#define DWC_MAX_COUNT 4095U
|
||||
|
||||
/*
|
||||
* Number of descriptors to allocate for each channel. This should be
|
||||
* made configurable somehow; preferably, the clients (at least the
|
||||
|
@ -672,7 +662,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
|
|||
|
||||
for (offset = 0; offset < len; offset += xfer_count << src_width) {
|
||||
xfer_count = min_t(size_t, (len - offset) >> src_width,
|
||||
DWC_MAX_COUNT);
|
||||
dwc->block_size);
|
||||
|
||||
desc = dwc_desc_get(dwc);
|
||||
if (!desc)
|
||||
|
@ -773,8 +763,8 @@ slave_sg_todev_fill_desc:
|
|||
desc->lli.sar = mem;
|
||||
desc->lli.dar = reg;
|
||||
desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
|
||||
if ((len >> mem_width) > DWC_MAX_COUNT) {
|
||||
dlen = DWC_MAX_COUNT << mem_width;
|
||||
if ((len >> mem_width) > dwc->block_size) {
|
||||
dlen = dwc->block_size << mem_width;
|
||||
mem += dlen;
|
||||
len -= dlen;
|
||||
} else {
|
||||
|
@ -833,8 +823,8 @@ slave_sg_fromdev_fill_desc:
|
|||
desc->lli.sar = reg;
|
||||
desc->lli.dar = mem;
|
||||
desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
|
||||
if ((len >> reg_width) > DWC_MAX_COUNT) {
|
||||
dlen = DWC_MAX_COUNT << reg_width;
|
||||
if ((len >> reg_width) > dwc->block_size) {
|
||||
dlen = dwc->block_size << reg_width;
|
||||
mem += dlen;
|
||||
len -= dlen;
|
||||
} else {
|
||||
|
@ -1217,7 +1207,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
|
|||
periods = buf_len / period_len;
|
||||
|
||||
/* Check for too big/unaligned periods and unaligned DMA buffer. */
|
||||
if (period_len > (DWC_MAX_COUNT << reg_width))
|
||||
if (period_len > (dwc->block_size << reg_width))
|
||||
goto out_err;
|
||||
if (unlikely(period_len & ((1 << reg_width) - 1)))
|
||||
goto out_err;
|
||||
|
@ -1383,6 +1373,7 @@ static int __devinit dw_probe(struct platform_device *pdev)
|
|||
bool autocfg;
|
||||
unsigned int dw_params;
|
||||
unsigned int nr_channels;
|
||||
unsigned int max_blk_size = 0;
|
||||
int irq;
|
||||
int err;
|
||||
int i;
|
||||
|
@ -1423,6 +1414,10 @@ static int __devinit dw_probe(struct platform_device *pdev)
|
|||
|
||||
dw->regs = regs;
|
||||
|
||||
/* get hardware configuration parameters */
|
||||
if (autocfg)
|
||||
max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
|
||||
|
||||
/* Calculate all channel mask before DMA setup */
|
||||
dw->all_chan_mask = (1 << nr_channels) - 1;
|
||||
|
||||
|
@ -1468,6 +1463,16 @@ static int __devinit dw_probe(struct platform_device *pdev)
|
|||
INIT_LIST_HEAD(&dwc->free_list);
|
||||
|
||||
channel_clear_bit(dw, CH_EN, dwc->mask);
|
||||
|
||||
/* hardware configuration */
|
||||
if (autocfg)
|
||||
/* Decode maximum block size for given channel. The
|
||||
* stored 4 bit value represents blocks from 0x00 for 3
|
||||
* up to 0x0a for 4095. */
|
||||
dwc->block_size =
|
||||
(4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
|
||||
else
|
||||
dwc->block_size = pdata->block_size;
|
||||
}
|
||||
|
||||
/* Clear all interrupts on all channels. */
|
||||
|
|
|
@ -193,6 +193,9 @@ struct dw_dma_chan {
|
|||
|
||||
unsigned int descs_allocated;
|
||||
|
||||
/* hardware configuration */
|
||||
unsigned int block_size;
|
||||
|
||||
/* configuration passed via DMA_SLAVE_CONFIG */
|
||||
struct dma_slave_config dma_sconfig;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* @nr_channels: Number of channels supported by hardware (max 8)
|
||||
* @is_private: The device channels should be marked as private and not for
|
||||
* by the general purpose DMA channel allocator.
|
||||
* @block_size: Maximum block size supported by the controller
|
||||
*/
|
||||
struct dw_dma_platform_data {
|
||||
unsigned int nr_channels;
|
||||
|
@ -29,6 +30,7 @@ struct dw_dma_platform_data {
|
|||
#define CHAN_PRIORITY_ASCENDING 0 /* chan0 highest */
|
||||
#define CHAN_PRIORITY_DESCENDING 1 /* chan7 highest */
|
||||
unsigned char chan_priority;
|
||||
unsigned short block_size;
|
||||
};
|
||||
|
||||
/* bursts size */
|
||||
|
|
Загрузка…
Ссылка в новой задаче