Thread (14 messages) 14 messages, 5 authors, 2017-08-02

[PATCH v2 5/5] ACPI/IORT: Add IORT named component memory address limits

From: Nate Watterson <hidden>
Date: 2017-08-02 17:31:12
Also in: linux-acpi, lkml

Hi Lorenzo,
I ran a quick test and this seems to work for memory_address_limit < 64,
however memory_address_limit == 64 yields a mask of 0x0.

-Nate

On 7/31/2017 11:23 AM, Lorenzo Pieralisi wrote:
quoted hunk ↗ jump to hunk
IORT named components provide firmware configuration describing
how many address bits a given device is capable of generating
to address memory.

Add code to the kernel to retrieve memory address limits
configuration for IORT named components and configure DMA masks
accordingly.

Signed-off-by: Lorenzo Pieralisi <redacted>
Cc: Will Deacon <redacted>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Nate Watterson <redacted>
---
  drivers/acpi/arm64/iort.c | 40 ++++++++++++++++++++++++++++++----------
  1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 67b85ae..b85d19f 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -680,6 +680,24 @@ static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
  	return ret ? NULL : ops;
  }
  
+static int nc_dma_get_range(struct device *dev, u64 *size)
+{
+	struct acpi_iort_node *node;
+	struct acpi_iort_named_component *ncomp;
+
+	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+			      iort_match_node_callback, dev);
+	if (!node)
+		return -ENODEV;
+
+	ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+	*size = ncomp->memory_address_limit >= 64 ? ~0ULL :
+			1ULL<<ncomp->memory_address_limit;
+
+	return 0;
+}
+
  /**
   * iort_dma_setup() - Set-up device DMA parameters.
   *
@@ -708,17 +726,19 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
  
  	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
  
-	if (dev_is_pci(dev)) {
+	if (dev_is_pci(dev))
  		ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
-		if (!ret) {
-			mask = __roundup_pow_of_two(dmaaddr + size) - 1;
-			/*
-			 * Limit coherent and dma mask based on size
-			 * retrieved from firmware.
-			 */
-			dev->coherent_dma_mask = mask;
-			*dev->dma_mask = mask;
-		}
+	else
+		ret = nc_dma_get_range(dev, &size);
+
+	if (!ret) {
+		mask = __roundup_pow_of_two(dmaaddr + size) - 1;
+		/*
+		 * Limit coherent and dma mask based on size
+		 * retrieved from firmware.
+		 */
+		dev->coherent_dma_mask = mask;
+		*dev->dma_mask = mask;
  	}
  
  	*dma_addr = dmaaddr;
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help