Skip to content

Commit 36834c6

Browse files
Akhil Rvinodkoul
authored andcommitted
dmaengine: tegra: Add terminate() for Tegra234
In certain cases where the DMA client bus gets corrupted or if the end device ceases to send/receive data, DMA can wait indefinitely for the data to be received/sent. Attempting to terminate the transfer will put the DMA in pause flush mode and it remains there. The channel is irrecoverable once this pause times out in Tegra194 and earlier chips. Whereas, from Tegra234, it can be recovered by disabling the channel and reprograming it. Hence add a new terminate() function that ignores the outcome of dma_pause() so that terminate_all() can proceed to disable the channel. Signed-off-by: Akhil R <[email protected]> Reviewed-by: Jon Hunter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 37a0d69 commit 36834c6

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

drivers/dma/tegra186-gpc-dma.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@
157157
* If any burst is in flight and DMA paused then this is the time to complete
158158
* on-flight burst and update DMA status register.
159159
*/
160-
#define TEGRA_GPCDMA_BURST_COMPLETE_TIME 20
161-
#define TEGRA_GPCDMA_BURST_COMPLETION_TIMEOUT 100
160+
#define TEGRA_GPCDMA_BURST_COMPLETE_TIME 10
161+
#define TEGRA_GPCDMA_BURST_COMPLETION_TIMEOUT 5000 /* 5 msec */
162162

163163
/* Channel base address offset from GPCDMA base address */
164164
#define TEGRA_GPCDMA_CHANNEL_BASE_ADD_OFFSET 0x20000
@@ -432,6 +432,17 @@ static int tegra_dma_device_resume(struct dma_chan *dc)
432432
return 0;
433433
}
434434

435+
static inline int tegra_dma_pause_noerr(struct tegra_dma_channel *tdc)
436+
{
437+
/* Return 0 irrespective of PAUSE status.
438+
* This is useful to recover channels that can exit out of flush
439+
* state when the channel is disabled.
440+
*/
441+
442+
tegra_dma_pause(tdc);
443+
return 0;
444+
}
445+
435446
static void tegra_dma_disable(struct tegra_dma_channel *tdc)
436447
{
437448
u32 csr, status;
@@ -1292,13 +1303,24 @@ static const struct tegra_dma_chip_data tegra194_dma_chip_data = {
12921303
.terminate = tegra_dma_pause,
12931304
};
12941305

1306+
static const struct tegra_dma_chip_data tegra234_dma_chip_data = {
1307+
.nr_channels = 31,
1308+
.channel_reg_size = SZ_64K,
1309+
.max_dma_count = SZ_1G,
1310+
.hw_support_pause = true,
1311+
.terminate = tegra_dma_pause_noerr,
1312+
};
1313+
12951314
static const struct of_device_id tegra_dma_of_match[] = {
12961315
{
12971316
.compatible = "nvidia,tegra186-gpcdma",
12981317
.data = &tegra186_dma_chip_data,
12991318
}, {
13001319
.compatible = "nvidia,tegra194-gpcdma",
13011320
.data = &tegra194_dma_chip_data,
1321+
}, {
1322+
.compatible = "nvidia,tegra234-gpcdma",
1323+
.data = &tegra234_dma_chip_data,
13021324
}, {
13031325
},
13041326
};

0 commit comments

Comments
 (0)