Thread (63 messages) 63 messages, 10 authors, 2014-06-02

[PATCH v3 4/7] of: configure the platform device dma parameters

From: arnd@arndb.de (Arnd Bergmann)
Date: 2014-05-05 20:56:39
Also in: linux-devicetree, lkml

On Monday 05 May 2014 14:45:21 Bjorn Helgaas wrote:
[+cc Ben, Chris]

On Fri, May 2, 2014 at 12:59 PM, Arnd Bergmann [off-list ref] wrote:
quoted
On Friday 02 May 2014 10:54:59 Bjorn Helgaas wrote:
quoted
quoted
+static void of_dma_configure(struct device *dev)
+{
+     u64 dma_addr, paddr, size;
+     int ret;
+
+     dev->coherent_dma_mask = DMA_BIT_MASK(32);
+     if (!dev->dma_mask)
+             dev->dma_mask = &dev->coherent_dma_mask;
+
+     /*
+      * if dma-coherent property exist, call arch hook to setup
+      * dma coherent operations.
+      */
+     if (of_dma_is_coherent(dev->of_node)) {
+             set_arch_dma_coherent_ops(dev);
+             dev_dbg(dev, "device is dma coherent\n");
+     }
+
+     /*
+      * if dma-ranges property doesn't exist - just return else
+      * setup the dma offset
+      */
+     ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size);
+     if ((ret == -ENODEV) || (ret < 0)) {
+             dev_dbg(dev, "no dma range information to setup\n");
+             return;
+     }
+
+     /* DMA ranges found. Calculate and set dma_pfn_offset */
+     dev->dma_pfn_offset = PFN_DOWN(paddr - dma_addr);
+     dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset);
Is this effectively the same as an IOMMU that applies a constant offset
to the bus address?  Could or should this be done by adding a simple IOMMU
driver instead of adding dma_pfn_offset to struct device?
We currently have two dma_map_ops variants on ARM (plus another set for
coherent/noncoherent differences, but we can ignore that for the sake
of this discussion): one that handles linear mappings and one that
handles IOMMUs by calling into the linux/iommu.h APIs.

I guess what you mean by 'a simple IOMMU driver' would be another
dma_map_ops implementation that is separate from real IOMMUs, right?
I suppose so; it seems like the offset could be managed inside
arm_dma_ops.  My idea of an IOMMU is something that maps bus addresses
to physical memory addresses.  That's what we're doing here; it's just
that the mapping function is very simple.  So why add something new in
struct device for it?

I think powerpc and tile do something similar in dma_direct_map_page()
and tile_pci_dma_map_page() (they store the offset in struct
dev_archdata).
Ah, so the only question is whether to store it in dev_archdata or
in device. I think the argument for using struct device directly
was that it lets us access this field from architecture independent
code. It's not important to the overall design though: we could easily
put it in dev_archdata and call an architecture specific function to
set it, if there are good reasons for keeping it out of the generic
device structure.

	Arnd
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help