diff mbox series

ARM64: Setup DMA32 zone size by bootargs

Message ID 20200916072206.27499-1-phil.chang@mediatek.com (mailing list archive)
State New, archived
Headers show
Series ARM64: Setup DMA32 zone size by bootargs | expand

Commit Message

Phil Chang (張世勳) Sept. 16, 2020, 7:22 a.m. UTC
this patch allowing the DMA32 zone be configurable in ARM64.

Signed-off-by: Alix Wu <alix.wu@mediatek.com>
Signed-off-by: YJ Chiang <yj.chiang@mediatek.com>
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
For some devices, the main memory split into 2 part due to the memory
architecture, the efficient and less inefficient part.
One of the use case is fine-tune the dma32 size to contain all the
efficient part of memory block on this kind of architecture

 .../admin-guide/kernel-parameters.txt         |  3 +++
 arch/arm64/include/asm/memory.h               |  2 ++
 arch/arm64/mm/init.c                          | 26 ++++++++++++++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

Comments

Christoph Hellwig Sept. 16, 2020, 8:37 a.m. UTC | #1
On Wed, Sep 16, 2020 at 03:22:06PM +0800, Phil Chang wrote:
> this patch allowing the DMA32 zone be configurable in ARM64.

Hell no.  The point of the DMA32 zone is that it is exactly the first
4GiG, and not some random size someone decided without explaining why.
diff mbox series

Patch

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdc1f33fd3d1..ef3bc3d4931a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -980,6 +980,9 @@ 
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
+	dma32_size=nn[KMG]  [KNL,BOOT,ARM64]
+			Forces the DMA32 zone size of <nn> in MB.
+
 	driver_async_probe=  [KNL]
 			List of driver names to be probed asynchronously.
 			Format: <driver_name1>,<driver_name2>...
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index afa722504bfd..710de08ae8ae 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -175,6 +175,8 @@  extern u64			kimage_vaddr;
 /* the offset between the kernel virtual and physical mappings */
 extern u64			kimage_voffset;
 
+extern phys_addr_t		dma32_zone_size;
+
 static inline unsigned long kaslr_offset(void)
 {
 	return kimage_vaddr - KIMAGE_VADDR;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 481d22c32a2e..fd1b85e131cc 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -60,6 +60,9 @@  EXPORT_SYMBOL(physvirt_offset);
 struct page *vmemmap __ro_after_init;
 EXPORT_SYMBOL(vmemmap);
 
+phys_addr_t dma32_zone_size __ro_after_init;
+EXPORT_SYMBOL(dma32_zone_size);
+
 /*
  * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
  * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@ -189,7 +192,12 @@  static void __init reserve_elfcorehdr(void)
 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
 {
 	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
-	return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+	phys_addr_t zone_size = (1ULL << zone_bits);
+
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) && zone_bits == 32 && dma32_zone_size)
+		zone_size = min(zone_size, dma32_zone_size);
+
+	return min(offset + zone_size, memblock_end_of_DRAM());
 }
 
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
@@ -242,6 +250,22 @@  static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
+static int __init setup_dma32_zone(char *p)
+{
+	unsigned long long size = memparse(p, NULL);
+
+	/* DMA32 zone size should never grater than 4G */
+	if (size > SZ_4G)
+		return -EINVAL;
+
+	pr_notice("Setup dma32 zone size to %llu Mb\n", size >> 20);
+	dma32_zone_size = size;
+
+	return 0;
+}
+
+early_param("dma32_size", setup_dma32_zone);
+
 static int __init early_init_dt_scan_usablemem(unsigned long node,
 		const char *uname, int depth, void *data)
 {