Hi, Jianmin, The title can be "LoongArch: Use acpi_arch_dma_setup() and remove ARCH_HAS_PHYS_TO_DMA", and please use resource_size() as arm64. Acked-by: Huacai Chen <chenhuacai@xxxxxxxxxxx> Huacai On Tue, Aug 30, 2022 at 11:01 AM Jianmin Lv <lvjianmin@xxxxxxxxxxx> wrote: > > 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, > , > , > ) > }) > > Signed-off-by: Jianmin Lv <lvjianmin@xxxxxxxxxxx> > --- > arch/loongarch/Kconfig | 1 - > arch/loongarch/kernel/dma.c | 52 +++++++++++++++++-------------------------- > arch/loongarch/kernel/setup.c | 2 +- > include/linux/acpi.h | 9 +++++--- > 4 files changed, 28 insertions(+), 36 deletions(-) > > diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig > index b57daee..9dedcf9 100644 > --- a/arch/loongarch/Kconfig > +++ b/arch/loongarch/Kconfig > @@ -7,7 +7,6 @@ config LOONGARCH > select ARCH_ENABLE_MEMORY_HOTPLUG > select ARCH_ENABLE_MEMORY_HOTREMOVE > select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI > - select ARCH_HAS_PHYS_TO_DMA > select ARCH_HAS_PTE_SPECIAL > select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST > select ARCH_INLINE_READ_LOCK if !PREEMPTION > diff --git a/arch/loongarch/kernel/dma.c b/arch/loongarch/kernel/dma.c > index 8c9b531..7a9c6a9 100644 > --- a/arch/loongarch/kernel/dma.c > +++ b/arch/loongarch/kernel/dma.c > @@ -2,39 +2,29 @@ > /* > * Copyright (C) 2020-2022 Loongson Technology Corporation Limited > */ > -#include <linux/init.h> > +#include <linux/acpi.h> > #include <linux/dma-direct.h> > -#include <linux/dma-mapping.h> > -#include <linux/dma-map-ops.h> > -#include <linux/swiotlb.h> > > -#include <asm/bootinfo.h> > -#include <asm/dma.h> > -#include <asm/loongson.h> > - > -/* > - * We extract 4bit node id (bit 44~47) from Loongson-3's > - * 48bit physical address space and embed it into 40bit. > - */ > - > -static int node_id_offset; > - > -dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) > -{ > - long nid = (paddr >> 44) & 0xf; > - > - return ((nid << 44) ^ paddr) | (nid << node_id_offset); > -} > - > -phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) > +void acpi_arch_dma_setup(struct device *dev) > { > - long nid = (daddr >> node_id_offset) & 0xf; > + 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); > + } > > - return ((nid << node_id_offset) ^ daddr) | (nid << 44); > -} > - > -void __init plat_swiotlb_setup(void) > -{ > - swiotlb_init(true, SWIOTLB_VERBOSE); > - node_id_offset = ((readl(LS7A_DMA_CFG) & LS7A_DMA_NODE_MASK) >> LS7A_DMA_NODE_SHF) + 36; > } > diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c > index c74860b..974f085 100644 > --- a/arch/loongarch/kernel/setup.c > +++ b/arch/loongarch/kernel/setup.c > @@ -247,7 +247,7 @@ static void __init arch_mem_init(char **cmdline_p) > sparse_init(); > memblock_set_bottom_up(true); > > - plat_swiotlb_setup(); > + swiotlb_init(true, SWIOTLB_VERBOSE); > > dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); > > diff --git a/include/linux/acpi.h b/include/linux/acpi.h > index 34e0545..33977b87 100644 > --- a/include/linux/acpi.h > +++ b/include/linux/acpi.h > @@ -278,14 +278,17 @@ int acpi_table_parse_madt(enum acpi_madt_type id, > > void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); > > +#if defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH) > +void acpi_arch_dma_setup(struct device *dev); > +#else > +static inline void acpi_arch_dma_setup(struct device *dev) { } > +#endif > + > #ifdef CONFIG_ARM64 > void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa); > -void acpi_arch_dma_setup(struct device *dev); > #else > static inline void > acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { } > -static inline void > -acpi_arch_dma_setup(struct device *dev) { } > #endif > > int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); > -- > 1.8.3.1 > >