Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 358501
b: refs/heads/master
c: 1b14090
h: refs/heads/master
i:
  358499: 447b346
v: v3
  • Loading branch information
Laxman Dewangan authored and Vinod Koul committed Jan 8, 2013
1 parent 52ba6a2 commit 0c33a24
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 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: e65f32ca21faed30ce37cd6480271697fe671f74
refs/heads/master: 1b140908c4cda43c653bb080c244d112e619008f
43 changes: 38 additions & 5 deletions trunk/drivers/dma/tegra20-apb-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
#define TEGRA_APBDMA_STATUS_COUNT_SHIFT 2
#define TEGRA_APBDMA_STATUS_COUNT_MASK 0xFFFC

#define TEGRA_APBDMA_CHAN_CSRE 0x00C
#define TEGRA_APBDMA_CHAN_CSRE_PAUSE (1 << 31)

/* AHB memory address */
#define TEGRA_APBDMA_CHAN_AHBPTR 0x010

Expand Down Expand Up @@ -112,10 +115,12 @@ struct tegra_dma;
* tegra_dma_chip_data Tegra chip specific DMA data
* @nr_channels: Number of channels available in the controller.
* @max_dma_count: Maximum DMA transfer count supported by DMA controller.
* @support_channel_pause: Support channel wise pause of dma.
*/
struct tegra_dma_chip_data {
int nr_channels;
int max_dma_count;
bool support_channel_pause;
};

/* DMA channel registers */
Expand Down Expand Up @@ -353,6 +358,32 @@ static void tegra_dma_global_resume(struct tegra_dma_channel *tdc)
spin_unlock(&tdma->global_lock);
}

static void tegra_dma_pause(struct tegra_dma_channel *tdc,
bool wait_for_burst_complete)
{
struct tegra_dma *tdma = tdc->tdma;

if (tdma->chip_data->support_channel_pause) {
tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE,
TEGRA_APBDMA_CHAN_CSRE_PAUSE);
if (wait_for_burst_complete)
udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME);
} else {
tegra_dma_global_pause(tdc, wait_for_burst_complete);
}
}

static void tegra_dma_resume(struct tegra_dma_channel *tdc)
{
struct tegra_dma *tdma = tdc->tdma;

if (tdma->chip_data->support_channel_pause) {
tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE, 0);
} else {
tegra_dma_global_resume(tdc);
}
}

static void tegra_dma_stop(struct tegra_dma_channel *tdc)
{
u32 csr;
Expand Down Expand Up @@ -408,7 +439,7 @@ static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc,
* If there is already IEC status then interrupt handler need to
* load new configuration.
*/
tegra_dma_global_pause(tdc, false);
tegra_dma_pause(tdc, false);
status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);

/*
Expand All @@ -418,7 +449,7 @@ static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc,
if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
dev_err(tdc2dev(tdc),
"Skipping new configuration as interrupt is pending\n");
tegra_dma_global_resume(tdc);
tegra_dma_resume(tdc);
return;
}

Expand All @@ -429,7 +460,7 @@ static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc,
nsg_req->ch_regs.csr | TEGRA_APBDMA_CSR_ENB);
nsg_req->configured = true;

tegra_dma_global_resume(tdc);
tegra_dma_resume(tdc);
}

static void tdc_start_head_req(struct tegra_dma_channel *tdc)
Expand Down Expand Up @@ -690,7 +721,7 @@ static void tegra_dma_terminate_all(struct dma_chan *dc)
goto skip_dma_stop;

/* Pause DMA before checking the queue status */
tegra_dma_global_pause(tdc, true);
tegra_dma_pause(tdc, true);

status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
Expand All @@ -708,7 +739,7 @@ static void tegra_dma_terminate_all(struct dma_chan *dc)
sgreq->dma_desc->bytes_transferred +=
get_current_xferred_count(tdc, sgreq, status);
}
tegra_dma_global_resume(tdc);
tegra_dma_resume(tdc);

skip_dma_stop:
tegra_dma_abort_all(tdc);
Expand Down Expand Up @@ -1175,13 +1206,15 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
static const struct tegra_dma_chip_data tegra20_dma_chip_data = {
.nr_channels = 16,
.max_dma_count = 1024UL * 64,
.support_channel_pause = false,
};

#if defined(CONFIG_OF)
/* Tegra30 specific DMA controller information */
static const struct tegra_dma_chip_data tegra30_dma_chip_data = {
.nr_channels = 32,
.max_dma_count = 1024UL * 64,
.support_channel_pause = false,
};

static const struct of_device_id tegra_dma_of_match[] __devinitconst = {
Expand Down

0 comments on commit 0c33a24

Please sign in to comment.