Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286127
b: refs/heads/master
c: 5cd326f
h: refs/heads/master
i:
  286125: 781a786
  286123: b277faf
  286119: 562c78a
  286111: 7bd206c
v: v3
  • Loading branch information
Narayanan G authored and Vinod Koul committed Dec 5, 2011
1 parent 3ecc2b9 commit 5302bcc
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f0d30f9ee333f4fb3458a9a33f7ead5269ea8f3
refs/heads/master: 5cd326fd27da347925019fcc041b79bad8dd55ed
6 changes: 5 additions & 1 deletion trunk/arch/arm/plat-nomadik/include/plat/ste_dma40.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ struct stedma40_half_channel_info {
* @dst_dev_type: Dst device type
* @src_info: Parameters for dst half channel
* @dst_info: Parameters for dst half channel
*
* @use_fixed_channel: if true, use physical channel specified by phy_channel
* @phy_channel: physical channel to use, only if use_fixed_channel is true
*
* This structure has to be filled by the client drivers.
* It is recommended to do all dma configurations for clients in the machine.
Expand All @@ -129,6 +130,9 @@ struct stedma40_chan_cfg {
int dst_dev_type;
struct stedma40_half_channel_info src_info;
struct stedma40_half_channel_info dst_info;

bool use_fixed_channel;
int phy_channel;
};

/**
Expand Down
51 changes: 42 additions & 9 deletions trunk/drivers/dma/ste_dma40.c
Original file line number Diff line number Diff line change
Expand Up @@ -1545,11 +1545,16 @@ static int d40_validate_conf(struct d40_chan *d40c,
return res;
}

static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src,
int log_event_line, bool is_log)
static bool d40_alloc_mask_set(struct d40_phy_res *phy,
bool is_src, int log_event_line, bool is_log,
bool *first_user)
{
unsigned long flags;
spin_lock_irqsave(&phy->lock, flags);

*first_user = ((phy->allocated_src | phy->allocated_dst)
== D40_ALLOC_FREE);

if (!is_log) {
/* Physical interrupts are masked per physical full channel */
if (phy->allocated_src == D40_ALLOC_FREE &&
Expand Down Expand Up @@ -1630,7 +1635,7 @@ static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src,
return is_free;
}

static int d40_allocate_channel(struct d40_chan *d40c)
static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
{
int dev_type;
int event_group;
Expand Down Expand Up @@ -1666,7 +1671,8 @@ static int d40_allocate_channel(struct d40_chan *d40c)
for (i = 0; i < d40c->base->num_phy_chans; i++) {

if (d40_alloc_mask_set(&phys[i], is_src,
0, is_log))
0, is_log,
first_phy_user))
goto found_phy;
}
} else
Expand All @@ -1676,7 +1682,8 @@ static int d40_allocate_channel(struct d40_chan *d40c)
if (d40_alloc_mask_set(&phys[i],
is_src,
0,
is_log))
is_log,
first_phy_user))
goto found_phy;
}
}
Expand All @@ -1692,6 +1699,25 @@ static int d40_allocate_channel(struct d40_chan *d40c)
/* Find logical channel */
for (j = 0; j < d40c->base->num_phy_chans; j += 8) {
int phy_num = j + event_group * 2;

if (d40c->dma_cfg.use_fixed_channel) {
i = d40c->dma_cfg.phy_channel;

if ((i != phy_num) && (i != phy_num + 1)) {
dev_err(chan2dev(d40c),
"invalid fixed phy channel %d\n", i);
return -EINVAL;
}

if (d40_alloc_mask_set(&phys[i], is_src, event_line,
is_log, first_phy_user))
goto found_log;

dev_err(chan2dev(d40c),
"could not allocate fixed phy channel %d\n", i);
return -EINVAL;
}

/*
* Spread logical channels across all available physical rather
* than pack every logical channel at the first available phy
Expand All @@ -1700,13 +1726,15 @@ static int d40_allocate_channel(struct d40_chan *d40c)
if (is_src) {
for (i = phy_num; i < phy_num + 2; i++) {
if (d40_alloc_mask_set(&phys[i], is_src,
event_line, is_log))
event_line, is_log,
first_phy_user))
goto found_log;
}
} else {
for (i = phy_num + 1; i >= phy_num; i--) {
if (d40_alloc_mask_set(&phys[i], is_src,
event_line, is_log))
event_line, is_log,
first_phy_user))
goto found_log;
}
}
Expand Down Expand Up @@ -2160,9 +2188,8 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
goto fail;
}
}
is_free_phy = (d40c->phy_chan == NULL);

err = d40_allocate_channel(d40c);
err = d40_allocate_channel(d40c, &is_free_phy);
if (err) {
chan_err(d40c, "Failed to allocate channel\n");
d40c->configured = false;
Expand All @@ -2189,6 +2216,12 @@ static int d40_alloc_chan_resources(struct dma_chan *chan)
D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
}

dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n",
chan_is_logical(d40c) ? "logical" : "physical",
d40c->phy_chan->num,
d40c->dma_cfg.use_fixed_channel ? ", fixed" : "");


/*
* Only write channel configuration to the DMA if the physical
* resource is free. In case of multiple logical channels
Expand Down

0 comments on commit 5302bcc

Please sign in to comment.