mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhenyu Wang <zhenyu.z.wang@intel.com>
To: Dave Airlie <airlied@linux.ie>,
	LKML <linux-kernel@vger.kernel.org>,
	Keith Packard <keithp@keithp.com>, Eric Anholt <eric@anholt.net>,
	"Gross, Mark" <mark.gross@intel.com>
Subject: [agp-mm][PATCH 2/4][AGP] Add generic support for graphics dma remapping
Date: Wed, 19 Dec 2007 13:28:53 +0800	[thread overview]
Message-ID: <20071219052853.GC24238@zhen-devel.sh.intel.com> (raw)
In-Reply-To: <20071219052030.GA24238@zhen-devel.sh.intel.com>

[agp-mm] [AGP] Add generic support for graphics dma remapping

New driver hooks for support graphics memory dma remapping
are introduced in this patch. It makes generic code can
tell if current device needs dma remapping, then call driver
provided interfaces for mapping and unmapping. Change has
also been made to handle scratch_page in remapping case.

Signed-off-by: Zhenyu Wang <zhenyu.z.wang@intel.com>
---
 drivers/char/agp/agp.h      |   13 +++++++++++++
 drivers/char/agp/backend.c  |   21 ++++++++++++++++++++-
 drivers/char/agp/generic.c  |   14 ++++++++++++++
 include/linux/agp_backend.h |    7 +++++++
 4 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 9ec9374..2c78a28 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -119,6 +119,17 @@ struct agp_bridge_driver {
 	void (*agp_destroy_page)(void *, int flags);
 	int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
 	void (*chipset_flush)(struct agp_bridge_data *);
+	/* Tell current graphics dma remapping engine status, there might
+	 * be driver or platform specific way to detect. */
+	int (*agp_require_remapping)(void);
+
+	/* This can support single page remapping via void *virt for like
+	 * scratch_page, or normal bunch of mem page range via struct
+	 * agp_memory *mem.
+	 */
+	int (*agp_map_page)(struct agp_memory *mem, void *virt, dma_addr_t *ret, int is_single);
+
+	void (*agp_unmap_page)(struct agp_memory *mem, dma_addr_t ret, int is_single);
 };
 
 struct agp_bridge_data {
@@ -133,6 +144,8 @@ struct agp_bridge_data {
 	u32 *gatt_table_real;
 	unsigned long scratch_page;
 	unsigned long scratch_page_real;
+	dma_addr_t scratch_page_dma;
+	u8 scratch_page_is_mapped;
 	unsigned long gart_bus_addr;
 	unsigned long gatt_bus_addr;
 	u32 mode;
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index f9c180c..7898051 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -151,7 +151,20 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 
 		bridge->scratch_page_real = virt_to_gart(addr);
 		bridge->scratch_page =
-		    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
+			bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
+
+		if (bridge->driver->agp_require_remapping &&
+				bridge->driver->agp_require_remapping()) {
+			if (bridge->driver->agp_map_page(NULL, addr, &bridge->scratch_page_dma, 1)) {
+				printk(KERN_ERR PFX "unable to map scratch page\n");
+				rc = -ENOMEM;
+				goto err_out;
+			}
+			bridge->scratch_page_is_mapped = TRUE;
+			bridge->scratch_page =
+				bridge->driver->mask_memory(bridge,
+						bridge->scratch_page_dma, 0);
+		}
 	}
 
 	size_value = bridge->driver->fetch_size();
@@ -189,6 +202,9 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 
 err_out:
 	if (bridge->driver->needs_scratch_page) {
+		if (bridge->scratch_page_is_mapped)
+			bridge->driver->agp_unmap_page(NULL, bridge->scratch_page_dma, 1);
+
 		bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real),
 						 AGP_PAGE_DESTROY_UNMAP);
 		flush_agp_mappings();
@@ -217,6 +233,9 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
 
 	if (bridge->driver->agp_destroy_page &&
 	    bridge->driver->needs_scratch_page) {
+		if (bridge->scratch_page_is_mapped)
+			bridge->driver->agp_unmap_page(NULL, bridge->scratch_page_dma, 1);
+
 		bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real),
 						 AGP_PAGE_DESTROY_UNMAP);
 		flush_agp_mappings();
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 8c67b4f..d2a502c 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -422,6 +422,14 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
 		curr->bridge->driver->cache_flush();
 		curr->is_flushed = TRUE;
 	}
+
+	if (curr->bridge->driver->agp_require_remapping &&
+			curr->bridge->driver->agp_require_remapping()) {
+		ret_val = curr->bridge->driver->agp_map_page(curr, NULL, NULL, 0);
+		if (ret_val)
+			return ret_val;
+	}
+
 	ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
 
 	if (ret_val != 0)
@@ -461,6 +469,12 @@ int agp_unbind_memory(struct agp_memory *curr)
 
 	curr->is_bound = FALSE;
 	curr->pg_start = 0;
+
+	if (curr->is_mapped) {
+		if (curr->bridge->driver->agp_unmap_page)
+			curr->bridge->driver->agp_unmap_page(curr, 0, 0);
+		curr->is_mapped = FALSE;
+	}
 	return 0;
 }
 EXPORT_SYMBOL(agp_unbind_memory);
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index 03e3454..64c7476 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -87,7 +87,14 @@ struct agp_memory {
 	u32 physical;
 	u8 is_bound;
 	u8 is_flushed;
+	u8 is_mapped;
         u8 vmalloc_flag;
+	/* Following are used in graphics dma remapping case,
+	 * for map/unmap via sg interfaces.
+	 */
+	struct scatterlist *sg_list;
+	int num_sg;
+	u8 sg_vmalloc_flag;
 };
 
 #define AGP_NORMAL_MEMORY 0
-- 
1.5.3.4


  parent reply	other threads:[~2007-12-19  5:36 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-18  5:08 [RFC][PATCH 0/4] enabling graphics memory " Zhenyu Wang
2007-12-18  5:09 ` [RFC][PATCH 1/4][intel_iommu] explicit export current graphics dmar status Zhenyu Wang
2007-12-18  5:11 ` [RFC][PATCH 2/4][AGP] Add generic support for graphics dma remapping Zhenyu Wang
2007-12-18  5:13 ` [RFC][PATCH 3/4][AGP] intel_agp: add support for graphics dma remapping on G33 Zhenyu Wang
2007-12-19  5:20 ` [agp-mm][PATCH 0/4] enabling graphics memory dma remapping Zhenyu Wang
2007-12-19  5:26   ` [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status Zhenyu Wang
2008-01-04  1:53     ` Zhenyu Wang
2008-01-08 20:44       ` mark gross
2008-01-25  3:02         ` Zhenyu Wang
2008-01-25 18:08           ` mark gross
2008-01-29  0:21             ` Zhenyu Wang
2007-12-19  5:28   ` Zhenyu Wang [this message]
2007-12-19  5:30   ` [agp-mm][PATCH 3/4][AGP] intel_agp: add support for graphics dma remapping on G33 Zhenyu Wang

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=20071219052853.GC24238@zhen-devel.sh.intel.com \
    --to=zhenyu.z.wang@intel.com \
    --cc=airlied@linux.ie \
    --cc=eric@anholt.net \
    --cc=keithp@keithp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.gross@intel.com \
    /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

Powered by JetHome