Skip to content

Commit 3a0c95b

Browse files
Akhil Rvinodkoul
authored andcommitted
dmaengine: tegra: Add support for dma-channel-mask
Add support for dma-channel-mask so that only the specified channels are used. This helps to reserve some channels for the firmware. This was initially achieved by limiting the channel number to 31 in the driver and adjusting the register address to skip channel0 which was reserved for a firmware. This is wrong and does not align with the hardware. Now, with this change, the driver can align more to the actual hardware which has 32 channels. But this implies that there will be a break in the ABI and the device tree need to be updated along with this change for the driver to pickup the right interrupt corresponding to the channel Reviewed-by: Jon Hunter <[email protected]> Link: https://lore.kernel.org/all/Y2EFoG1H9YpfxRjs@orome/ Signed-off-by: Akhil R <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent d57b2a6 commit 3a0c95b

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

drivers/dma/tegra186-gpc-dma.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,10 @@
161161
#define TEGRA_GPCDMA_BURST_COMPLETION_TIMEOUT 5000 /* 5 msec */
162162

163163
/* Channel base address offset from GPCDMA base address */
164-
#define TEGRA_GPCDMA_CHANNEL_BASE_ADD_OFFSET 0x20000
164+
#define TEGRA_GPCDMA_CHANNEL_BASE_ADDR_OFFSET 0x10000
165+
166+
/* Default channel mask reserving channel0 */
167+
#define TEGRA_GPCDMA_DEFAULT_CHANNEL_MASK 0xfffffffe
165168

166169
struct tegra_dma;
167170
struct tegra_dma_channel;
@@ -246,6 +249,7 @@ struct tegra_dma {
246249
const struct tegra_dma_chip_data *chip_data;
247250
unsigned long sid_m2d_reserved;
248251
unsigned long sid_d2m_reserved;
252+
u32 chan_mask;
249253
void __iomem *base_addr;
250254
struct device *dev;
251255
struct dma_device dma_dev;
@@ -1288,23 +1292,23 @@ static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
12881292
}
12891293

12901294
static const struct tegra_dma_chip_data tegra186_dma_chip_data = {
1291-
.nr_channels = 31,
1295+
.nr_channels = 32,
12921296
.channel_reg_size = SZ_64K,
12931297
.max_dma_count = SZ_1G,
12941298
.hw_support_pause = false,
12951299
.terminate = tegra_dma_stop_client,
12961300
};
12971301

12981302
static const struct tegra_dma_chip_data tegra194_dma_chip_data = {
1299-
.nr_channels = 31,
1303+
.nr_channels = 32,
13001304
.channel_reg_size = SZ_64K,
13011305
.max_dma_count = SZ_1G,
13021306
.hw_support_pause = true,
13031307
.terminate = tegra_dma_pause,
13041308
};
13051309

13061310
static const struct tegra_dma_chip_data tegra234_dma_chip_data = {
1307-
.nr_channels = 31,
1311+
.nr_channels = 32,
13081312
.channel_reg_size = SZ_64K,
13091313
.max_dma_count = SZ_1G,
13101314
.hw_support_pause = true,
@@ -1380,15 +1384,28 @@ static int tegra_dma_probe(struct platform_device *pdev)
13801384
}
13811385
stream_id = iommu_spec->ids[0] & 0xffff;
13821386

1387+
ret = device_property_read_u32(&pdev->dev, "dma-channel-mask",
1388+
&tdma->chan_mask);
1389+
if (ret) {
1390+
dev_warn(&pdev->dev,
1391+
"Missing dma-channel-mask property, using default channel mask %#x\n",
1392+
TEGRA_GPCDMA_DEFAULT_CHANNEL_MASK);
1393+
tdma->chan_mask = TEGRA_GPCDMA_DEFAULT_CHANNEL_MASK;
1394+
}
1395+
13831396
INIT_LIST_HEAD(&tdma->dma_dev.channels);
13841397
for (i = 0; i < cdata->nr_channels; i++) {
13851398
struct tegra_dma_channel *tdc = &tdma->channels[i];
13861399

1400+
/* Check for channel mask */
1401+
if (!(tdma->chan_mask & BIT(i)))
1402+
continue;
1403+
13871404
tdc->irq = platform_get_irq(pdev, i);
13881405
if (tdc->irq < 0)
13891406
return tdc->irq;
13901407

1391-
tdc->chan_base_offset = TEGRA_GPCDMA_CHANNEL_BASE_ADD_OFFSET +
1408+
tdc->chan_base_offset = TEGRA_GPCDMA_CHANNEL_BASE_ADDR_OFFSET +
13921409
i * cdata->channel_reg_size;
13931410
snprintf(tdc->name, sizeof(tdc->name), "gpcdma.%d", i);
13941411
tdc->tdma = tdma;
@@ -1449,8 +1466,8 @@ static int tegra_dma_probe(struct platform_device *pdev)
14491466
return ret;
14501467
}
14511468

1452-
dev_info(&pdev->dev, "GPC DMA driver register %d channels\n",
1453-
cdata->nr_channels);
1469+
dev_info(&pdev->dev, "GPC DMA driver register %lu channels\n",
1470+
hweight_long(tdma->chan_mask));
14541471

14551472
return 0;
14561473
}
@@ -1473,6 +1490,9 @@ static int __maybe_unused tegra_dma_pm_suspend(struct device *dev)
14731490
for (i = 0; i < tdma->chip_data->nr_channels; i++) {
14741491
struct tegra_dma_channel *tdc = &tdma->channels[i];
14751492

1493+
if (!(tdma->chan_mask & BIT(i)))
1494+
continue;
1495+
14761496
if (tdc->dma_desc) {
14771497
dev_err(tdma->dev, "channel %u busy\n", i);
14781498
return -EBUSY;
@@ -1492,6 +1512,9 @@ static int __maybe_unused tegra_dma_pm_resume(struct device *dev)
14921512
for (i = 0; i < tdma->chip_data->nr_channels; i++) {
14931513
struct tegra_dma_channel *tdc = &tdma->channels[i];
14941514

1515+
if (!(tdma->chan_mask & BIT(i)))
1516+
continue;
1517+
14951518
tegra_dma_program_sid(tdc, tdc->stream_id);
14961519
}
14971520

0 commit comments

Comments
 (0)