diff mbox series

[V3,2/2] LoongArch: Remove ARCH_HAS_PHYS_TO_DMA

Message ID 20220830030139.29899-3-lvjianmin@loongson.cn (mailing list archive)
State Superseded, archived
Headers show
Series DMA: update acpi_dma_get_range to return dma map regions | expand

Commit Message

吕建民 Aug. 30, 2022, 3:01 a.m. UTC
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@loongson.cn>
---
 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(-)

Comments

Huacai Chen Sept. 5, 2022, 2:42 p.m. UTC | #1
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@loongson.cn>


Huacai


On Tue, Aug 30, 2022 at 11:01 AM Jianmin Lv <lvjianmin@loongson.cn> 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@loongson.cn>
> ---
>  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
>
>
吕建民 Sept. 6, 2022, 12:34 p.m. UTC | #2
Hi, Huacai

Ok, thanks, I'll change title in V4. There is *not* size calculation in
this patch, so the patch does not need resource_size() as in 
acpi_dma_get_range().

On 2022/9/5 下午10:42, Huacai Chen wrote:
> 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@loongson.cn>
> 
> 
> Huacai
> 
> 
> On Tue, Aug 30, 2022 at 11:01 AM Jianmin Lv <lvjianmin@loongson.cn> 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@loongson.cn>
>> ---
>>   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
>>
>>
diff mbox series

Patch

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);