Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: stefan.wahren@i2se.com, f.fainelli@gmail.com,
	catalin.marinas@arm.com, phil@raspberrypi.org,
	robin.murphy@arm.com, Jisheng.Zhang@synaptics.com,
	mbrugger@suse.com, will@kernel.org, hch@lst.de,
	Nicolas Saenz Julienne <nsaenzjulienne@suse.de>,
	m.szyprowski@samsung.com
Subject: [RFC 2/4] arm64: mm: parse dma-ranges in order to better estimate arm64_dma_phys_limit
Date: Wed, 17 Jul 2019 17:31:33 +0200
Message-ID: <20190717153135.15507-3-nsaenzjulienne@suse.de> (raw)
In-Reply-To: <20190717153135.15507-1-nsaenzjulienne@suse.de>

The dma physical limit has so far been calculated based on the memory
size and the assumption that dma would be at least able to address the
first 4 GB. This turned out no to be true with the Raspberry Pi 4
which, on it's main interconnect, can only address the first GB of
memory, even though it might have up to 4 GB.

With the current miscalculated dma physical limit the contiguous memory
reserve is located in an inaccessible area for most of the board's
devices.

To solve this we now scan the device tree for the 'dma-ranges' property
on the root or interconnect nodes, which allows us to calculate the
lowest common denominator dma physical limit. If no dma-ranges is
available, we'll default to the old scheme.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 arch/arm64/mm/init.c | 61 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 6112d6c90fa8..5708adf0db52 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -163,14 +163,67 @@ static void __init reserve_elfcorehdr(void)
 {
 }
 #endif /* CONFIG_CRASH_DUMP */
+
+static int __init early_init_dt_scan_dma_ranges(unsigned long node,
+		const char *uname, int depth, void *data)
+{
+	phys_addr_t *dma_phys_limit = data;
+	u64 phys_addr, dma_addr, size;
+	int dma_addr_cells;
+	const __be32 *reg;
+	const void *prop;
+	int len;
+
+	/* We keep looking if this isn't the root node or an interconnect */
+	if (!(depth == 0 ||
+	    (depth == 1 && of_flat_dt_is_compatible(node, "simple-bus"))))
+		return 0;
+
+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	if (prop)
+		dma_addr_cells = be32_to_cpup(prop);
+	else
+		dma_addr_cells = 1; /* arm64's default addr_cell size */
+
+	reg = of_get_flat_dt_prop(node, "dma-ranges", &len);
+	if (!reg ||
+	    len < (dma_addr_cells + dt_root_addr_cells + dt_root_size_cells))
+		return 0;
+
+	dma_addr = dt_mem_next_cell(dma_addr_cells, &reg);
+	phys_addr = dt_mem_next_cell(dt_root_addr_cells, &reg);
+	size = dt_mem_next_cell(dt_root_size_cells, &reg);
+
+	/* We're in ZONE_DMA32 */
+	if (size > (1ULL << 32))
+		size = 1ULL << 32;
+
+	if (*dma_phys_limit > (phys_addr + size))
+		*dma_phys_limit = phys_addr + size;
+
+	return 0;
+}
+
 /*
- * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It
- * currently assumes that for memory starting above 4G, 32-bit devices will
- * use a DMA offset.
+ * Return the maximum physical address for ZONE_DMA32. It currently assumes
+ * that for memory starting above 4G, 32-bit devices will use a DMA offset.
  */
 static phys_addr_t __init max_zone_dma_phys(void)
 {
-	phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
+	phys_addr_t dma_phys_limit = ~0;
+	phys_addr_t offset;
+
+	/*
+	 * We walk the whole fdt looking for nodes with dma-ranges, calculate
+	 * the max_zone_dma_phys for them and keep going. We end-up getting the
+	 * lowest common denominator of all the matches.
+	 */
+	of_scan_flat_dt(early_init_dt_scan_dma_ranges, &dma_phys_limit);
+	if (dma_phys_limit != ~0)
+		return dma_phys_limit;
+
+	/* If no dma-ranges property was found we try to infer the value */
+	offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32);
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply index

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-17 15:31 [RFC 0/4] Raspberry Pi 4 DMA addressing support Nicolas Saenz Julienne
2019-07-17 15:31 ` [RFC 1/4] arm64: mm: use arm64_dma_phys_limit instead of calling max_zone_dma_phys() Nicolas Saenz Julienne
2019-07-17 15:31 ` Nicolas Saenz Julienne [this message]
2019-07-24 13:54   ` [RFC 2/4] arm64: mm: parse dma-ranges in order to better estimate arm64_dma_phys_limit Catalin Marinas
2019-07-17 15:31 ` [RFC 3/4] dma-direct: add dma_direct_min_mask Nicolas Saenz Julienne
2019-07-18  9:15   ` Christoph Hellwig
2019-07-18 11:18     ` Nicolas Saenz Julienne
2019-07-19 13:08       ` Nicolas Saenz Julienne
2019-07-24 13:51         ` Catalin Marinas
2019-07-24 13:56           ` Christoph Hellwig
2019-07-24 14:27             ` Nicolas Saenz Julienne
2019-07-17 15:31 ` [RFC 4/4] arm64: mm: set direct_dma_min_mask according to dma-ranges Nicolas Saenz Julienne

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190717153135.15507-3-nsaenzjulienne@suse.de \
    --to=nsaenzjulienne@suse.de \
    --cc=Jisheng.Zhang@synaptics.com \
    --cc=catalin.marinas@arm.com \
    --cc=f.fainelli@gmail.com \
    --cc=hch@lst.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mbrugger@suse.com \
    --cc=phil@raspberrypi.org \
    --cc=robin.murphy@arm.com \
    --cc=stefan.wahren@i2se.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org infradead-linux-arm-kernel@archiver.kernel.org
	public-inbox-index linux-arm-kernel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox