From 361bb935f7531cffb9e5ffa083364e7456155534 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 20 Jun 2010 21:24:52 +0000 Subject: [PATCH] --- yaml --- r: 207359 b: refs/heads/master c: ef1872ec652b3bc472d6c0995d0b64d5058878ea h: refs/heads/master i: 207357: 5cbfe29323fa684ba9bd309aef4df16475e2e838 207355: 753eb6dbe83e6793bad475f44e7dcf754743e50e 207351: fa201acebd7f7cd95d1aa399bacd20252c26c07f 207343: 160e5755843e291da74043661904fa6ceba36017 207327: 0506efce994e392b3df38b9fa54e57605ee6981d 207295: ad4292048064e8652435514bd52bfd78031e7430 207231: 4d730c35200c4b9a0ce31c9b95cb1a2030ad2139 207103: 016038080b2bd131dce11acc1a25239d1e261b7c 206847: 29db89118f965885fbd2aadb37100d5f1393edc4 v: v3 --- [refs] | 2 +- trunk/drivers/dma/ste_dma40.c | 64 ++++++++++++++++---------------- trunk/drivers/dma/ste_dma40_ll.h | 3 ++ 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/[refs] b/[refs] index f07fbcf34888..813cf829573d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 941b77a3b6946dd6223a029007f695aa841b6d34 +refs/heads/master: ef1872ec652b3bc472d6c0995d0b64d5058878ea diff --git a/trunk/drivers/dma/ste_dma40.c b/trunk/drivers/dma/ste_dma40.c index 4618d6c727c8..9655452f0b69 100644 --- a/trunk/drivers/dma/ste_dma40.c +++ b/trunk/drivers/dma/ste_dma40.c @@ -1210,30 +1210,6 @@ static int d40_allocate_channel(struct d40_chan *d40c) } -static int d40_config_chan(struct d40_chan *d40c, - struct stedma40_chan_cfg *info) -{ - - /* Fill in basic CFG register values */ - d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, - &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN); - - if (d40c->log_num != D40_PHY_CHAN) { - d40_log_cfg(&d40c->dma_cfg, - &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); - - if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) - d40c->lcpa = d40c->base->lcpa_base + - d40c->dma_cfg.src_dev_type * 32; - else - d40c->lcpa = d40c->base->lcpa_base + - d40c->dma_cfg.dst_dev_type * 32 + 16; - } - - /* Write channel configuration to the DMA */ - return d40_config_write(d40c); -} - static int d40_config_memcpy(struct d40_chan *d40c) { dma_cap_mask_t cap = d40c->chan.device->cap_mask; @@ -1691,20 +1667,21 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) unsigned long flags; struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); - + bool is_free_phy; spin_lock_irqsave(&d40c->lock, flags); d40c->completed = chan->cookie = 1; /* * If no dma configuration is set (channel_type == 0) - * use default configuration + * use default configuration (memcpy) */ if (d40c->dma_cfg.channel_type == 0) { err = d40_config_memcpy(d40c); if (err) goto err_alloc; } + is_free_phy = (d40c->phy_chan == NULL); err = d40_allocate_channel(d40c); if (err) { @@ -1713,12 +1690,35 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) goto err_alloc; } - err = d40_config_chan(d40c, &d40c->dma_cfg); - if (err) { - dev_err(&d40c->chan.dev->device, - "[%s] Failed to configure channel\n", - __func__); - goto err_config; + /* Fill in basic CFG register values */ + d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, + &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN); + + if (d40c->log_num != D40_PHY_CHAN) { + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE; + else + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.dst_dev_type * + D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA; + } + + /* + * Only write channel configuration to the DMA if the physical + * resource is free. In case of multiple logical channels + * on the same physical resource, only the first write is necessary. + */ + if (is_free_phy) { + err = d40_config_write(d40c); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to configure channel\n", + __func__); + } } spin_unlock_irqrestore(&d40c->lock, flags); diff --git a/trunk/drivers/dma/ste_dma40_ll.h b/trunk/drivers/dma/ste_dma40_ll.h index 2029280cb332..c081f28ec1e3 100644 --- a/trunk/drivers/dma/ste_dma40_ll.h +++ b/trunk/drivers/dma/ste_dma40_ll.h @@ -13,6 +13,9 @@ #define D40_DREG_PCDELTA (8 * 4) #define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */ +#define D40_LCPA_CHAN_SIZE 32 +#define D40_LCPA_CHAN_DST_DELTA 16 + #define D40_TYPE_TO_GROUP(type) (type / 16) #define D40_TYPE_TO_EVENT(type) (type % 16)