mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kumar Gala <galak@kernel.crashing.org>
To: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: jeremy@goop.org, hch@infradead.org, linux-kernel@vger.kernel.org,
	mingo@elte.hu, ian.campbell@citrix.com,
	beckyb@kernel.crashing.org
Subject: Re: [PATCH 4/7] swiotlb: Allow arch override of address_needs_mapping
Date: Thu, 9 Apr 2009 15:25:00 -0500 (CDT)	[thread overview]
Message-ID: <Pine.LNX.4.64.0904091524001.14308@localhost.localdomain> (raw)
In-Reply-To: <F46E8277-0165-4C4F-9DFE-7697881536C0@kernel.crashing.org>

Here's the WIP patch for the PPC changes to give some sense of what we
need out of swiotlb for PPC.

- k

---
 arch/powerpc/include/asm/dma-mapping.h     |   18 ++++
 arch/powerpc/include/asm/scatterlist.h     |    6 +-
 arch/powerpc/include/asm/swiotlb.h         |   15 +++
 arch/powerpc/kernel/Makefile               |    1 +
 arch/powerpc/kernel/dma-swiotlb.c          |  154 ++++++++++++++++++++++++++++
 arch/powerpc/kernel/dma.c                  |    2 +-
 arch/powerpc/kernel/pci-common.c           |    2 +
 arch/powerpc/kernel/setup_32.c             |    4 +
 10 files changed, 211 insertions(+), 7 deletions(-)
 create mode 100644 arch/powerpc/include/asm/swiotlb.h
 create mode 100644 arch/powerpc/kernel/dma-swiotlb.c

diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index c69f2b5..db6edfe 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -16,8 +16,18 @@
 #include <linux/dma-attrs.h>
 #include <asm/io.h>

+#ifdef CONFIG_SWIOTLB
+#include <asm/swiotlb.h>
+#endif
+
 #define DMA_ERROR_CODE		(~(dma_addr_t)0x0)

+/* Some dma direct funcs must be visible for use in other dma_ops */
+extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+				       dma_addr_t *dma_handle, gfp_t flag);
+extern void dma_direct_free_coherent(struct device *dev, size_t size,
+				     void *vaddr, dma_addr_t dma_handle);
+
 #ifdef CONFIG_NOT_COHERENT_CACHE
 /*
  * DMA-consistent mapping functions for PowerPCs that don't support
@@ -112,11 +122,19 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
 	if (unlikely(dev == NULL))
 		return NULL;

+	/* BGILL - temp code to look for problems */
+	if(dev->archdata.dma_ops == NULL)
+		printk(KERN_EMERG "dev %s has null dma_ops\n", dev->bus->name);
+
 	return dev->archdata.dma_ops;
 }

 static inline void set_dma_ops(struct device *dev, struct dma_mapping_ops *ops)
 {
+	printk(KERN_EMERG "Setting dma_ops to %s\n",
+	       (ops == &dma_direct_ops) ? "dma_direct_ops" :
+	       ((ops == &swiotlb_dma_ops) ? "swiotlb_dma_ops" : "unknown"));
+
 	dev->archdata.dma_ops = ops;
 }

diff --git a/arch/powerpc/include/asm/scatterlist.h b/arch/powerpc/include/asm/scatterlist.h
index fcf7d55..912bf59 100644
--- a/arch/powerpc/include/asm/scatterlist.h
+++ b/arch/powerpc/include/asm/scatterlist.h
@@ -21,7 +21,7 @@ struct scatterlist {
 	unsigned int offset;
 	unsigned int length;

-	/* For TCE support */
+	/* For TCE or SWIOTLB support */
 	dma_addr_t dma_address;
 	u32 dma_length;
 };
@@ -34,11 +34,7 @@ struct scatterlist {
  * is 0.
  */
 #define sg_dma_address(sg)	((sg)->dma_address)
-#ifdef __powerpc64__
 #define sg_dma_len(sg)		((sg)->dma_length)
-#else
-#define sg_dma_len(sg)		((sg)->length)
-#endif

 #ifdef __powerpc64__
 #define ISA_DMA_THRESHOLD	(~0UL)
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
new file mode 100644
index 0000000..cbfce6c
--- /dev/null
+++ b/arch/powerpc/include/asm/swiotlb.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_SWIOTLB_H
+#define __ASM_SWIOTLB_H
+
+#include <linux/swiotlb.h>
+
+extern int swiotlb_force;
+extern int swiotlb;
+extern struct dma_mapping_ops swiotlb_dma_ops;
+
+int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
+				       size_t size);
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+#endif /* __ASM_SWIOTLB_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 71901fb..34c0a95 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_SWIOTLB)		+= dma-swiotlb.o

 pci64-$(CONFIG_PPC64)		+= pci_dn.o isa-bridge.o
 obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
new file mode 100644
index 0000000..639f3bc
--- /dev/null
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ *
+ * swiotlb dma ops and functions required by the swiotlb code.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/pfn.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <asm/machdep.h>
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+#include <asm/abs_addr.h>
+
+int swiotlb __read_mostly;
+
+unsigned long get_dma_direct_offset(struct device *dev);
+
+void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr)
+{
+	unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr));
+	void *pageaddr = page_address(pfn_to_page(pfn));
+
+	if(pageaddr != NULL)
+		return pageaddr + (addr % PAGE_SIZE);
+	return NULL;
+}
+
+#if 0 /* BGILL - don't need */
+/* This can only be called on pages with a kernel mapping */
+dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, void *addr)
+{
+	return swiotlb_phys_to_bus(hwdev, virt_to_abs((unsigned long)addr));
+}
+#endif
+
+dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
+{
+	return (paddr + get_dma_direct_offset(hwdev));
+}
+
+phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
+
+{
+	return (baddr - get_dma_direct_offset(hwdev));
+}
+
+/*
+ * Eventually, we should really be looking at some per-device
+ * quantity stored in archdata, and not a global value, since this is
+ * only needed for devices like PCI that use part of their 32 bit address
+ * space for something other than mapping memory.
+ *
+ * For now, require swiotlb mapping above MAX_32B_DIRECT_DMA_ADDR for devs
+ * that are not 64-bit capable.  This should be determined using the PCI mem
+ * allocations in the devtree. -beckyb
+ */
+#define MAX_32B_DIRECT_DMA_ADDR 0x80000000
+
+/* determine if an address needs bounce buffering via swiotlb. */
+int
+swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr,
+				   size_t size)
+{
+	dma_addr_t mask = DMA_BIT_MASK(32);
+
+	/* Max dma_address we can access without bounce buffering */
+	dma_addr_t max = swiotlb_phys_to_bus(hwdev, MAX_32B_DIRECT_DMA_ADDR);
+
+	/* BGILL - can we get rid of this? */
+	if (hwdev && hwdev->dma_mask)
+		mask = *hwdev->dma_mask;
+
+	if ((mask <= DMA_BIT_MASK(36)) && (addr + size > max))
+		return 1;
+
+	return !is_buffer_dma_capable(mask, addr, size);
+}
+
+/*
+ * At the moment, all platforms that use this code only require
+ * swiotlb to be used if we're operating on HIGHMEM.  Since
+ * we don't ever call anything other than map_sg, unmap_sg,
+ * map_page, and unmap_page on highmem, use normal dma_ops
+ * for everything else.
+ */
+struct dma_mapping_ops swiotlb_dma_ops = {
+#if 0
+	.alloc_coherent = dma_direct_alloc_coherent,
+	.free_coherent = dma_direct_free_coherent,
+#else
+	.alloc_coherent = swiotlb_alloc_coherent,
+	.free_coherent = swiotlb_free_coherent,
+#endif
+	.map_sg = swiotlb_map_sg_attrs,
+	.unmap_sg = swiotlb_unmap_sg_attrs,
+	.dma_supported = swiotlb_dma_supported,
+	.map_page = swiotlb_map_page,
+	.unmap_page = swiotlb_unmap_page,
+	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+	.sync_sg_for_device = swiotlb_sync_sg_for_device
+};
+
+static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	struct device *dev = data;
+
+	/* We are only intereted in device addition */
+	if (action != BUS_NOTIFY_ADD_DEVICE)
+		return 0;
+
+#if 0 /* BGILL - should look like this; use other form for debug */
+	if(dma_get_mask(dev) < DMA_BIT_MASK(36))
+		set_dma_ops(dev, &swiotlb_dma_ops);
+#else
+	if(!dev->dma_mask) {
+		printk(KERN_EMERG "ERROR: no dma_mask set for dev\n");
+		set_dma_ops(dev, &swiotlb_dma_ops);
+	}
+	else if(*dev->dma_mask < DMA_BIT_MASK(36)) {
+		set_dma_ops(dev, &swiotlb_dma_ops);
+	}
+	else
+		printk(KERN_EMERG "ERROR; fall thru with direct_ops\n");
+#endif
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
+	.notifier_call = ppc_swiotlb_bus_notify,
+	.priority = 0,
+};
+
+static struct notifier_block ppc_swiotlb_of_bus_notifier = {
+	.notifier_call = ppc_swiotlb_bus_notify,
+	.priority = 0,
+};
+
+static int __init setup_bus_notifier(void)
+{
+	bus_register_notifier(&platform_bus_type, &ppc_swiotlb_plat_bus_notifier);
+	bus_register_notifier(&of_platform_bus_type, &ppc_swiotlb_of_bus_notifier);
+
+	return 0;
+}
+
+machine_arch_initcall(mpc86xx_hpcn, setup_bus_notifier);
+
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 53c7788..62d80c4 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -19,7 +19,7 @@
  * default the offset is PCI_DRAM_OFFSET.
  */

-static unsigned long get_dma_direct_offset(struct device *dev)
+unsigned long get_dma_direct_offset(struct device *dev)
 {
 	if (dev)
 		return (unsigned long)dev->archdata.dma_data;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 9e1ca74..f038b13 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -332,6 +332,10 @@ void __init setup_arch(char **cmdline_p)
 		ppc_md.setup_arch();
 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);

+	/* Allow iotlb to do it's setup */
+#ifdef CONFIG_SWIOTLB
+	swiotlb_init();
+#endif
 	paging_init();

 	/* Initialize the MMU context management stuff */

  reply	other threads:[~2009-04-09 20:26 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-08 14:09 [PATCH V3 0/7] swiotlb: changes for powerpc/highmem Kumar Gala
2009-04-08 14:09 ` [PATCH 1/7] swiotlb: comment corrections (no code changes) Kumar Gala
2009-04-08 14:09   ` [PATCH 2/7] swiotlb: fix compile warning Kumar Gala
2009-04-08 14:09     ` [PATCH 3/7] swiotlb: map_page fix for highmem systems Kumar Gala
2009-04-08 14:09       ` [PATCH 4/7] swiotlb: Allow arch override of address_needs_mapping Kumar Gala
2009-04-08 14:09         ` [PATCH 5/7] swiotlb: Rename unmap_single to do_unmap_single Kumar Gala
2009-04-08 14:09           ` [PATCH 6/7] swiotlb: Use swiotlb_sync_single instead of duplicating code Kumar Gala
2009-04-08 14:09             ` [PATCH 7/7] swiotlb: Change swiotlb_bus_to[phys,virt] prototypes Kumar Gala
2009-04-08 15:25               ` [tip:core/iommu] swiotlb: change " Becky Bruce
2009-04-08 15:25             ` [tip:core/iommu] swiotlb: use swiotlb_sync_single instead of duplicating code Becky Bruce
2009-04-08 15:25           ` [tip:core/iommu] swiotlb: rename unmap_single to do_unmap_single Becky Bruce
2009-04-08 15:25         ` [tip:core/iommu] swiotlb: allow arch override of address_needs_mapping Becky Bruce
2009-04-08 20:38         ` [PATCH 4/7] swiotlb: Allow " Christoph Hellwig
2009-04-08 20:56           ` Kumar Gala
2009-04-08 21:15             ` FUJITA Tomonori
2009-04-08 21:55               ` Jeremy Fitzhardinge
2009-04-08 22:10                 ` FUJITA Tomonori
2009-04-08 22:36                   ` Jeremy Fitzhardinge
2009-04-08 23:01                     ` FUJITA Tomonori
2009-04-08 23:16                       ` Jeremy Fitzhardinge
2009-04-08 23:37                         ` FUJITA Tomonori
2009-04-09  0:09                           ` Jeremy Fitzhardinge
2009-04-09  4:43                             ` Kumar Gala
2009-04-09 18:34                             ` FUJITA Tomonori
2009-04-09 19:19                               ` Jeremy Fitzhardinge
2009-04-09 19:43                                 ` FUJITA Tomonori
2009-04-09 19:50                                 ` FUJITA Tomonori
2009-04-09 19:54                                   ` Jeremy Fitzhardinge
2009-04-09  4:59                       ` Kumar Gala
2009-04-09 18:50                         ` FUJITA Tomonori
2009-04-09 20:10                           ` Kumar Gala
2009-04-09 20:25                             ` Kumar Gala [this message]
2009-04-08 22:24               ` Christoph Hellwig
2009-04-08 15:24       ` [tip:core/iommu] swiotlb: map_page fix for highmem systems Becky Bruce
2009-04-08 15:24     ` [tip:core/iommu] swiotlb: fix compile warning Becky Bruce
2009-04-08 15:24   ` [tip:core/iommu] swiotlb: comment corrections Becky Bruce
2009-04-08 14:21 ` [PATCH V3 0/7] swiotlb: changes for powerpc/highmem Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2009-04-04  1:56 [PATCH V2 " Becky Bruce
2009-04-04  1:56 ` [PATCH 1/7] swiotlb: comment corrections (no code changes) Becky Bruce
2009-04-04  1:56   ` [PATCH 2/7] swiotlb: fix compile warning Becky Bruce
2009-04-04  1:56     ` [PATCH 3/7] swiotlb: map_page fix for highmem systems Becky Bruce
2009-04-04  1:56       ` [PATCH 4/7] swiotlb: Allow arch override of address_needs_mapping Becky Bruce

Reply instructions:

You may reply publicly 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=Pine.LNX.4.64.0904091524001.14308@localhost.localdomain \
    --to=galak@kernel.crashing.org \
    --cc=beckyb@kernel.crashing.org \
    --cc=fujita.tomonori@lab.ntt.co.jp \
    --cc=hch@infradead.org \
    --cc=ian.campbell@citrix.com \
    --cc=jeremy@goop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®