All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alan Cox <alan@linux.jf.intel.com>
To: greg@kroah.com, linux-kernel@vger.kernel.org
Subject: [PATCH 6/8] gma500: GEM - now we have the basics we shall stick pins in it
Date: Tue, 19 Apr 2011 15:28:21 +0100	[thread overview]
Message-ID: <20110419142809.16479.83632.stgit@localhost.localdomain> (raw)
In-Reply-To: <20110419142432.16479.89255.stgit@localhost.localdomain>

Signed-off-by: Alan Cox <alan@linux.intel.com>
---

 drivers/staging/gma500/psb_gtt.c           |   70 +++++++++++++++++++++-------
 drivers/staging/gma500/psb_gtt.h           |   13 ++---
 drivers/staging/gma500/psb_intel_display.c |   33 ++++++++-----
 3 files changed, 80 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 090d30e..a991c12 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -66,7 +66,6 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
 	return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
 }
 
-
 /**
  *	psb_gtt_insert	-	put an object into the GART
  *	@dev: our DRM device
@@ -77,21 +76,19 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
  *
  *	FIXME: gtt lock ?
  */
-int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
+static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
 {
 	u32 *gtt_slot, pte;
 	int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
 	struct page **pages;
 	int i;
 
-	if (r->stolen)
-		return 0;
 	if (r->pages == NULL) {
 		WARN_ON(1);
 		return -EINVAL;
 	}
 
-	WARN_ON(r->in_gart);	/* refcount these maybe ? */
+	WARN_ON(r->stolen);	/* refcount these maybe ? */
 
 	gtt_slot = psb_gtt_entry(dev, r);
 	pages = r->pages;
@@ -118,16 +115,14 @@ int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
  *	page table entries with the dummy page
  */
 
-void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
+static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 *gtt_slot, pte;
 	int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
 	int i;
 
-	if (r->stolen)
-		return;
-	WARN_ON(!r->in_gart);
+	WARN_ON(r->stolen);
 
 	gtt_slot = psb_gtt_entry(dev, r);
 	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
@@ -146,7 +141,7 @@ void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
  *	Pin and build an in kernel list of the pages that back our GEM object.
  *	While we hold this the pages cannot be swapped out
  */
-int psb_gtt_attach_pages(struct gtt_range *gt)
+static int psb_gtt_attach_pages(struct gtt_range *gt)
 {
 	struct inode *inode;
 	struct address_space *mapping;
@@ -189,13 +184,11 @@ err:
  *	must have been removed from the GART as they could now be paged out
  *	and move bus address.
  */
-void psb_gtt_detach_pages(struct gtt_range *gt)
+static void psb_gtt_detach_pages(struct gtt_range *gt)
 {
 	int i;
 	int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
 
-	WARN_ON(gt->in_gart);
-
 	for (i = 0; i < pages; i++) {
 		/* FIXME: do we need to force dirty */
 		set_page_dirty(gt->pages[i]);
@@ -207,6 +200,50 @@ void psb_gtt_detach_pages(struct gtt_range *gt)
 }
 
 /*
+ *	Manage pinning of resources into the GART
+ */
+
+int psb_gtt_pin(struct drm_device *dev, struct gtt_range *gt)
+{
+	int ret;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev_priv->gtt_mutex);
+
+	if (gt->in_gart == 0 && gt->stolen == 0) {
+		ret = psb_gtt_attach_pages(gt);
+		if (ret < 0)
+			goto out;
+		ret = psb_gtt_insert(dev, gt);
+		if (ret < 0) {
+			psb_gtt_detach_pages(gt);
+			goto out;
+		}
+	}
+	gt->in_gart++;
+out:
+	mutex_unlock(&dev_priv->gtt_mutex);
+	return ret;
+}
+
+void psb_gtt_unpin(struct drm_device *dev, struct gtt_range *gt)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev_priv->gtt_mutex);
+
+	WARN_ON(!gt->in_gart);
+
+	gt->in_gart--;
+	if (gt->in_gart == 0 && gt->stolen == 0) {
+		psb_gtt_remove(dev, gt);
+		psb_gtt_detach_pages(gt);
+	}
+
+	mutex_unlock(&dev_priv->gtt_mutex);
+}
+	
+/*
  *	GTT resource allocator - allocate and manage GTT address space
  */
 
@@ -265,10 +302,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
 static void psb_gtt_destroy(struct kref *kref)
 {
 	struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
-	if (gt->in_gart && !gt->stolen)
-		psb_gtt_remove(gt->gem.dev, gt);
-	if (gt->pages)
-		psb_gtt_detach_pages(gt);
+	WARN_ON(gt->in_gart && !gt->stolen);
 	release_resource(&gt->resource);
 	kfree(gt);
 }
@@ -345,6 +379,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
 	int ret = 0;
 	uint32_t pte;
 
+	mutex_init(&dev_priv->gtt_mutex);
+
 	dev_priv->pg = pg = psb_gtt_alloc(dev);
 	if (pg == NULL)
 	        return -ENOMEM;
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index b5d6530..dc553e0 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -44,18 +44,17 @@ struct gtt_range {
 	struct resource resource;
 	u32 offset;
 	struct kref kref;
-        struct drm_gem_object gem;	/* GEM high level stuff */
-        int in_gart;			/* Currently in the GART */
-        int stolen;			/* Backed from stolen RAM */
-        struct page **pages;		/* Backing pages if present */
+	struct drm_gem_object gem;	/* GEM high level stuff */
+	int in_gart;			/* Currently in the GART (ref ct) */
+        bool stolen;			/* Backed from stolen RAM */
+	struct page **pages;		/* Backing pages if present */
 };
 
-extern int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r);
-extern void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r);
-
 extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
 						const char *name, int backed);
 extern void psb_gtt_kref_put(struct gtt_range *gt);
 extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
+extern int psb_gtt_pin(struct drm_device *dev, struct gtt_range *gt);
+extern void psb_gtt_unpin(struct drm_device *dev, struct gtt_range *gt);
 
 #endif
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 4d384d5..b5a36d2 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -341,7 +341,6 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
 	/* struct drm_i915_master_private *master_priv; */
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 	int pipe = psb_intel_crtc->pipe;
 	unsigned long start, offset;
 	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
@@ -1020,8 +1019,6 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 				 uint32_t width, uint32_t height)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv =
-				(struct drm_psb_private *)dev->dev_private;
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	int pipe = psb_intel_crtc->pipe;
 	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
@@ -1048,6 +1045,9 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
 		/* Unpin the old GEM object */
 		if (psb_intel_crtc->cursor_obj) {
+                	gt = container_of(psb_intel_crtc->cursor_obj,
+                	                        struct gtt_range, gem);
+			psb_gtt_unpin(crtc->dev, gt);
 			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
 			psb_intel_crtc->cursor_obj = NULL;
 		}
@@ -1070,19 +1070,17 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 		return -ENOMEM;
 	}
 
-	/*insert this bo into gtt*/
-	DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
-						__func__, handle);
+	gt = container_of(obj, struct gtt_range, gem);
 
-/* Pin : FIXME
+	/* Pin the memory into the GTT */
+	ret = psb_gtt_pin(crtc->dev, gt);
 	if (ret) {
-		DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
+		DRM_ERROR("Can not pin down handle 0x%x\n", handle);
 		return ret;
 	}
-*/
-	gt = container_of(obj, struct gtt_range, gem);
 
-	addr = gt->resource.start;
+
+	addr = gt->offset;	/* Or resource.start ??? */
 
 	psb_intel_crtc->cursor_addr = addr;
 
@@ -1099,6 +1097,9 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
 	/* unpin the old bo */
 	if (psb_intel_crtc->cursor_obj && psb_intel_crtc->cursor_obj != obj) {
+               	gt = container_of(psb_intel_crtc->cursor_obj,
+               	                        struct gtt_range, gem);
+		psb_gtt_unpin(crtc->dev, gt);
 		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
 		psb_intel_crtc->cursor_obj = obj;
 	}
@@ -1301,8 +1302,16 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
 static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct gtt_range *gt;
 
-	/* FIXME: do we need to put the final GEM cursor ? */
+	/* Unpin the old GEM object */
+	if (psb_intel_crtc->cursor_obj) {
+		gt = container_of(psb_intel_crtc->cursor_obj,
+						struct gtt_range, gem);
+		psb_gtt_unpin(crtc->dev, gt);
+		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+		psb_intel_crtc->cursor_obj = NULL;
+	}
 	kfree(psb_intel_crtc->crtc_state);
 	drm_crtc_cleanup(crtc);
 	kfree(psb_intel_crtc);


  parent reply	other threads:[~2011-04-19 14:49 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-19 14:26 [PATCH 0/8] Further clean up and setup Alan Cox
2011-04-19 14:27 ` [PATCH 1/8] gma500: add the ability to request backed space or not Alan Cox
2011-04-20 20:31   ` Greg KH
2011-04-20 21:21     ` Alan Cox
2011-04-21  5:05       ` Greg KH
2011-04-21  5:06       ` Greg KH
2011-04-21  8:49         ` Alan Cox
2011-04-26  0:15           ` Greg KH
2011-04-19 14:27 ` [PATCH 2/8] gma500: begin adding GEM Alan Cox
2011-04-19 14:27 ` [PATCH 3/8] gma500: Add support for inserting and removing pages from the GART Alan Cox
2011-04-19 14:27 ` [PATCH 4/8] gma500: Begin the GEMification of the cursor code Alan Cox
2011-04-19 14:28 ` [PATCH 5/8] gma500: GEMify the frame buffer base bits Alan Cox
2011-04-19 14:28 ` Alan Cox [this message]
2011-04-19 14:28 ` [PATCH 7/8] gma500: prune some unused variables Alan Cox
2011-04-19 14:28 ` [PATCH 8/8] gma500: allow non stolen page backed framebuffer Alan Cox

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=20110419142809.16479.83632.stgit@localhost.localdomain \
    --to=alan@linux.jf.intel.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.