linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: greg@kroah.com, linux-kernel@vger.kernel.org
Subject: [PATCH 03/29] gma500: Ensure the frame buffer has a linear virtual mapping
Date: Thu, 16 Jun 2011 17:07:01 +0100	[thread overview]
Message-ID: <20110616160642.6039.31781.stgit@localhost.localdomain> (raw)
In-Reply-To: <20110616160104.6039.44019.stgit@localhost.localdomain>

From: Alan Cox <alan@linux.intel.com>

We need this for the framebuffer in order to ensure that the kernel
framebuffer layer can handle it when using KMS. Except for the base
framebuffer this isn't a concern.

Add an npage field to the gtt as too many copies of the page calculation
are getting spread around the code.

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

 drivers/staging/gma500/psb_fb.c  |   47 ++++++++++++++++++++++++--------------
 drivers/staging/gma500/psb_fb.h  |    1 +
 drivers/staging/gma500/psb_gtt.c |   18 ++++++---------
 drivers/staging/gma500/psb_gtt.h |    5 ++--
 4 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index b276fe9..4b05cdc 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -254,17 +254,13 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 				vma->vm_pgoff, fb_screen_base,
                                 dev_priv->vram_addr);
 
-        /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
-	if (1 || fb_screen_base == dev_priv->vram_addr) {
-		vma->vm_ops = &psbfb_vm_ops;
-		vma->vm_private_data = (void *)psbfb;
-		vma->vm_flags |= VM_RESERVED | VM_IO |
-						VM_MIXEDMAP | VM_DONTEXPAND;
-	} else {
-	        /* GTT memory backed by kernel/user pages, needs a different
-	           approach ? - GEM ? */
-	}
-
+        /* If this is a GEM object then info->screen_base is the virtual
+           kernel remapping of the object. FIXME: Review if this is
+           suitable for our mmap work */
+	vma->vm_ops = &psbfb_vm_ops;
+	vma->vm_private_data = (void *)psbfb;
+	vma->vm_flags |= VM_RESERVED | VM_IO |
+					VM_MIXEDMAP | VM_DONTEXPAND;
 	return 0;
 }
 
@@ -349,8 +345,6 @@ err:
  *
  *	FIXME: console speed up - allocate twice the space if room and use
  *	hardware scrolling for acceleration.
- *	FIXME: we need to vm_map_ram  a linear mapping if the object has to
- *	be GEM host mapped, otherwise the cfb layer's brain will fall out.
  */
 static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
 {
@@ -439,10 +433,22 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	info->fix.smem_start = dev->mode_config.fb_base;
 	info->fix.smem_len = size;
 
-	/* Accessed via stolen memory directly, This only works for stolem
-	   memory however. Need to address this once we start using gtt
-	   pages we allocate. FIXME: vm_map_ram for that case */
-	info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
+	if (backing->stolen) {
+		/* Accessed stolen memory directly */
+		info->screen_base = (char *)dev_priv->vram_addr +
+							backing->offset;
+	} else {
+		/* Pin the pages into the GTT and create a mapping to them */
+		psb_gtt_pin(backing);
+		info->screen_base = vm_map_ram(backing->pages, backing->npage,
+				-1, PAGE_KERNEL);
+		if (info->screen_base == NULL) {
+			psb_gtt_unpin(backing);
+			ret = -ENOMEM;
+			goto out_err0;
+		}
+		psbfb->vm_map = 1;
+	}
 	info->screen_size = size;
 	memset(info->screen_base, 0, size);
 
@@ -570,6 +576,13 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
 
 	if (fbdev->psb_fb_helper.fbdev) {
 		info = fbdev->psb_fb_helper.fbdev;
+
+		/* If this is our base framebuffer then kill any virtual map
+		   for the framebuffer layer and unpin it */
+		if (psbfb->vm_map) {
+			vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
+			psb_gtt_unpin(psbfb->gtt);
+		}
 		/* FIXME: this is a bit more inside knowledge than I'd like
 		   but I don't see how to make a fake GEM object of the
 		   stolen space nicely */
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index c8ec0d6..2153c74 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -33,6 +33,7 @@ struct psb_framebuffer {
 	struct address_space *addr_space;
 	struct fb_info *fbdev;
 	struct gtt_range *gtt;
+	bool vm_map;		/* True if we must undo a vm_map_ram */
 };
 
 struct psb_fbdev {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 2ddab50..6a24246 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -79,7 +79,6 @@ u32 *psb_gtt_entry(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 = resource_size(&r->resource) >> PAGE_SHIFT;
 	struct page **pages;
 	int i;
 
@@ -94,10 +93,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
 	pages = r->pages;
 
 	/* Make sure changes are visible to the GPU */
-	set_pages_array_uc(pages, numpages);
+	set_pages_array_uc(pages, r->npage);
 
 	/* Write our page entries into the GTT itself */
-	for (i = 0; i < numpages; i++) {
+	for (i = 0; i < r->npage; i++) {
 		pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
 		iowrite32(pte, gtt_slot++);
 	}
@@ -120,7 +119,6 @@ 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 = resource_size(&r->resource) >> PAGE_SHIFT;
 	int i;
 
 	WARN_ON(r->stolen);
@@ -128,10 +126,10 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
 	gtt_slot = psb_gtt_entry(dev, r);
 	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
 
-	for (i = 0; i < numpages; i++)
+	for (i = 0; i < r->npage; i++)
 		iowrite32(pte, gtt_slot++);
 	ioread32(gtt_slot - 1);
-	set_pages_array_wb(r->pages, numpages);
+	set_pages_array_wb(r->pages, r->npage);
 }
 
 /**
@@ -149,7 +147,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
 	struct address_space *mapping;
 	int i;
 	struct page *p;
-	int pages = resource_size(&gt->resource) >> PAGE_SHIFT;
+	int pages = gt->gem.size / PAGE_SIZE;
 
 	WARN_ON(gt->pages);
 
@@ -160,6 +158,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
 	gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
 	if (gt->pages == NULL)
 		return -ENOMEM;
+	gt->npage = pages;
+
 	for (i = 0; i < pages; i++) {
 		/* FIXME: review flags later */
 		p = read_cache_page_gfp(mapping, i,
@@ -191,9 +191,7 @@ err:
 static void psb_gtt_detach_pages(struct gtt_range *gt)
 {
 	int i;
-	int pages = resource_size(&gt->resource) >> PAGE_SHIFT;
-
-	for (i = 0; i < pages; i++) {
+	for (i = 0; i < gt->npage; i++) {
 		/* FIXME: do we need to force dirty */
 		set_page_dirty(gt->pages[i]);
 		/* Undo the reference we took when populating the table */
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 535ae00..37287eb 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -46,9 +46,10 @@ struct gtt_range {
 	struct kref kref;
 	struct drm_gem_object gem;	/* GEM high level stuff */
 	int in_gart;			/* Currently in the GART (ref ct) */
-        bool stolen;			/* Backed from stolen RAM */
-        bool mmapping;			/* Is mmappable */
+	bool stolen;			/* Backed from stolen RAM */
+	bool mmapping;			/* Is mmappable */
 	struct page **pages;		/* Backing pages if present */
+	int npage;			/* Number of backing pages */
 };
 
 extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


  parent reply	other threads:[~2011-06-16 16:18 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-16 16:05 [PATCH 00/29] gma500: pending patches versus next 20110616 Alan Cox
2011-06-16 16:06 ` [PATCH 01/29] gma500: fix warnings Alan Cox
2011-06-16 16:06 ` [PATCH 02/29] gma500: Make GTT pages uncached Alan Cox
2011-06-16 16:07 ` Alan Cox [this message]
2011-06-28 21:18   ` [PATCH 03/29] gma500: Ensure the frame buffer has a linear virtual mapping Greg KH
2011-06-28 22:02     ` Alan Cox
2011-06-28 22:09       ` Jiri Kosina
2011-06-28 22:15         ` Jiri Kosina
2011-06-28 22:42           ` Alan Cox
2011-06-28 22:54             ` Jiri Kosina
2011-06-28 22:41         ` Alan Cox
2011-06-28 22:18       ` Joe Perches
2011-06-16 16:07 ` [PATCH 04/29] gma500: Set the correct bits according to the pipe Alan Cox
2011-06-16 16:07 ` [PATCH 05/29] gma500: Fix uninitialized variable and style issues Alan Cox
2011-06-16 16:08 ` [PATCH 06/29] gma500: revamp frame buffer creation and handling Alan Cox
2011-06-28 21:20   ` Greg KH
2011-06-16 16:08 ` [PATCH 07/29] gma500: Do sane FB cleanup Alan Cox
2011-06-16 16:08 ` [PATCH 08/29] gma500: trim some of the debug Alan Cox
2011-06-16 16:09 ` [PATCH 09/29] gma500: polish for completion of this phase Alan Cox
2011-06-16 16:34 ` [PATCH 10/29] gma500: 2D acceleration tidying Alan Cox
2011-06-16 16:34 ` [PATCH 11/29] gma500: nuke the last bits of TTM code Alan Cox
2011-06-16 16:34 ` [PATCH 12/29] gma500: nuke the PSB debug stuff Alan Cox
2011-06-16 16:36 ` [PATCH 13/29] gma500: Kill spare kref Alan Cox
2011-06-16 16:37 ` [PATCH 14/29] gma500: GEM glue Alan Cox
2011-06-16 16:37 ` [PATCH 15/29] gma500: Use the GEM tweaks to provide a GEM frame buffer Alan Cox
2011-06-16 16:37 ` [PATCH 16/29] gma500: CodingStyle pass Alan Cox
2011-06-16 16:38 ` [PATCH 17/29] gma500: 2D polish Alan Cox
2011-06-16 16:38 ` [PATCH 18/29] gma500: Medfield support Alan Cox
2011-06-16 16:40 ` [PATCH 19/29] gma500: Move our other GEM helper into the bits want to push into GEM Alan Cox
2011-06-16 16:40 ` [PATCH 20/29] gma500: Extract BIOSisy stuff from psb_drv Alan Cox
2011-06-16 16:41 ` [PATCH 21/29] gma500: psb_fb tidy/cleanup pass Alan Cox
2011-06-16 16:41 ` [PATCH 22/29] gma500: Update the GEM todo Alan Cox
2011-06-16 16:41 ` [PATCH 23/29] gma500: Only fiddle with clock gating on PSB Alan Cox
2011-06-16 16:42 ` [PATCH 24/29] gma500: being abstracting out devices a bit more Alan Cox
2011-06-16 16:42 ` [PATCH 25/29] gma500: continue abstracting platform specific code Alan Cox
2011-06-16 16:42 ` [PATCH 26/29] gma500: Fix early Medfield crash Alan Cox
2011-06-16 16:43 ` [PATCH 27/29] gma500: Read the GCT panel type information for Medfield Alan Cox
2011-06-16 16:43 ` [PATCH 28/29] gma500: enable Medfield CRTC support Alan Cox
2011-06-16 16:43 ` [PATCH 29/29] gma500: drivers/staging/gma501/psb_intel_display.c: fix build Alan Cox
2011-06-28 22:02 [PATCH 00/29] GMA500 updates Alan Cox
2011-06-28 22:03 ` [PATCH 03/29] gma500: Ensure the frame buffer has a linear virtual mapping 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=20110616160642.6039.31781.stgit@localhost.localdomain \
    --to=alan@lxorguk.ukuu.org.uk \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).