mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 18:41:23 +00:00
c78c43fe7d
Use _DMA defined in ACPI spec for translation between DMA address and CPU address, and implement acpi_arch_dma_setup for initializing dev->dma_range_map, where acpi_dma_get_range is called for parsing _DMA. e.g. If we have two dma ranges: cpu address dma address size offset 0x200080000000 0x2080000000 0x400000000 0x1fe000000000 0x400080000000 0x4080000000 0x400000000 0x3fc000000000 _DMA for pci devices should be declared in host bridge as flowing: Name (_DMA, ResourceTemplate() { QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0x0, 0x4080000000, 0x447fffffff, 0x3fc000000000, 0x400000000, , , ) QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0x0, 0x2080000000, 0x247fffffff, 0x1fe000000000, 0x400000000, , , ) }) Acked-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
31 lines
709 B
C
31 lines
709 B
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
*/
|
|
#include <linux/acpi.h>
|
|
#include <linux/dma-direct.h>
|
|
|
|
void acpi_arch_dma_setup(struct device *dev)
|
|
{
|
|
int ret;
|
|
u64 mask, end = 0;
|
|
const struct bus_dma_region *map = NULL;
|
|
|
|
ret = acpi_dma_get_range(dev, &map);
|
|
if (!ret && map) {
|
|
const struct bus_dma_region *r = map;
|
|
|
|
for (end = 0; r->size; r++) {
|
|
if (r->dma_start + r->size - 1 > end)
|
|
end = r->dma_start + r->size - 1;
|
|
}
|
|
|
|
mask = DMA_BIT_MASK(ilog2(end) + 1);
|
|
dev->bus_dma_limit = end;
|
|
dev->dma_range_map = map;
|
|
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
|
|
*dev->dma_mask = min(*dev->dma_mask, mask);
|
|
}
|
|
|
|
}
|