Commit daab23f1 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman

gma500: revamp frame buffer creation and handling

Restructure this to work the same way as the i915 frame buffer does. That
cleans up various chunks of code.

We can now set a mode in modetest but mode restore is a bit iffy
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9460e84a
...@@ -148,7 +148,7 @@ static void psbfb_fillrect_accel(struct fb_info *info, ...@@ -148,7 +148,7 @@ static void psbfb_fillrect_accel(struct fb_info *info,
const struct fb_fillrect *r) const struct fb_fillrect *r)
{ {
struct psb_fbdev *fbdev = info->par; struct psb_fbdev *fbdev = info->par;
struct psb_framebuffer *psbfb = fbdev->pfb; struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev; struct drm_device *dev = psbfb->base.dev;
struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
...@@ -291,7 +291,7 @@ static void psbfb_copyarea_accel(struct fb_info *info, ...@@ -291,7 +291,7 @@ static void psbfb_copyarea_accel(struct fb_info *info,
const struct fb_copyarea *a) const struct fb_copyarea *a)
{ {
struct psb_fbdev *fbdev = info->par; struct psb_fbdev *fbdev = info->par;
struct psb_framebuffer *psbfb = fbdev->pfb; struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev; struct drm_device *dev = psbfb->base.dev;
struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
...@@ -360,19 +360,12 @@ void psbfb_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -360,19 +360,12 @@ void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
int psbfb_sync(struct fb_info *info) int psbfb_sync(struct fb_info *info)
{ {
struct psb_fbdev *fbdev = info->par; struct psb_fbdev *fbdev = info->par;
struct psb_framebuffer *psbfb = fbdev->pfb; struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev; struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long _end = jiffies + DRM_HZ; unsigned long _end = jiffies + DRM_HZ;
int busy = 0; int busy = 0;
#if 0
/* Just a way to quickly test if cmd issue explodes */
u32 test[2] = {
PSB_2D_FENCE_BH,
};
psbfb_2d_submit(dev_priv, test, 1);
#endif
/* /*
* First idle the 2D engine. * First idle the 2D engine.
*/ */
......
This diff is collapsed.
...@@ -38,7 +38,7 @@ struct psb_framebuffer { ...@@ -38,7 +38,7 @@ struct psb_framebuffer {
struct psb_fbdev { struct psb_fbdev {
struct drm_fb_helper psb_fb_helper; struct drm_fb_helper psb_fb_helper;
struct psb_framebuffer *pfb; struct psb_framebuffer pfb;
}; };
......
...@@ -51,6 +51,7 @@ void psb_gem_free_object(struct drm_gem_object *obj) ...@@ -51,6 +51,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
} }
drm_gem_object_release(obj); drm_gem_object_release(obj);
/* This must occur last as it frees up the memory of the GEM object */ /* This must occur last as it frees up the memory of the GEM object */
pr_err("GEM destroyed %p, %p\n", gtt, obj);
psb_gtt_free_range(obj->dev, gtt); psb_gtt_free_range(obj->dev, gtt);
} }
...@@ -176,21 +177,28 @@ static int psb_gem_create(struct drm_file *file, ...@@ -176,21 +177,28 @@ static int psb_gem_create(struct drm_file *file,
size = roundup(size, PAGE_SIZE); size = roundup(size, PAGE_SIZE);
dev_err(dev->dev, "GEM creating %lld\n", size);
/* Allocate our object - for now a direct gtt range which is not /* Allocate our object - for now a direct gtt range which is not
stolen memory backed */ stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0); r = psb_gtt_alloc_range(dev, size, "gem", 0);
if (r == NULL) if (r == NULL) {
dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
return -ENOSPC; return -ENOSPC;
}
/* Initialize the extra goodies GEM needs to do all the hard work */ /* Initialize the extra goodies GEM needs to do all the hard work */
if (drm_gem_object_init(dev, &r->gem, size) != 0) { if (drm_gem_object_init(dev, &r->gem, size) != 0) {
psb_gtt_free_range(dev, r); psb_gtt_free_range(dev, r);
/* GEM doesn't give an error code and we don't have an /* GEM doesn't give an error code and we don't have an
EGEMSUCKS so make something up for now - FIXME */ EGEMSUCKS so make something up for now - FIXME */
dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM; return -ENOMEM;
} }
/* Give the object a handle so we can carry it more easily */ /* Give the object a handle so we can carry it more easily */
ret = drm_gem_handle_create(file, &r->gem, &handle); ret = drm_gem_handle_create(file, &r->gem, &handle);
if (ret) { if (ret) {
dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
&r->gem, size);
drm_gem_object_release(&r->gem); drm_gem_object_release(&r->gem);
psb_gtt_free_range(dev, r); psb_gtt_free_range(dev, r);
return ret; return ret;
...@@ -198,6 +206,8 @@ static int psb_gem_create(struct drm_file *file, ...@@ -198,6 +206,8 @@ static int psb_gem_create(struct drm_file *file,
/* We have the initial and handle reference but need only one now */ /* We have the initial and handle reference but need only one now */
drm_gem_object_unreference(&r->gem); drm_gem_object_unreference(&r->gem);
*handlep = handle; *handlep = handle;
dev_err(dev->dev, "GEM handle %x for %p OK\n",
handle, &r->gem);
return 0; return 0;
} }
...@@ -273,9 +283,12 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -273,9 +283,12 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
something from beneath our feet */ something from beneath our feet */
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
dev_err(dev->dev, "Fault on GTT %p\n", r);
/* For now the mmap pins the object and it stays pinned. As things /* For now the mmap pins the object and it stays pinned. As things
stand that will do us no harm */ stand that will do us no harm */
if (r->mmapping == 0) { if (r->mmapping == 0) {
dev_err(dev->dev, "Need to pin %p\n", r);
ret = psb_gtt_pin(r); ret = psb_gtt_pin(r);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("gma500: pin failed: %d\n", ret); DRM_ERROR("gma500: pin failed: %d\n", ret);
...@@ -289,10 +302,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -289,10 +302,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start) page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT; >> PAGE_SHIFT;
dev_err(dev->dev, "Page offset %p %d\n", r, (int)page_offset);
/* CPU view of the page, don't go via the GART for CPU writes */ /* CPU view of the page, don't go via the GART for CPU writes */
pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT; pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
dev_err(dev->dev, "PFN %ld for VA %p = %d\n", pfn, vmf->virtual_address, ret);
fail: fail:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
switch (ret) { switch (ret) {
......
...@@ -314,6 +314,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, ...@@ -314,6 +314,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
len, start, end, PAGE_SIZE, NULL, NULL); len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) { if (ret == 0) {
gt->offset = gt->resource.start - r->start; gt->offset = gt->resource.start - r->start;
dev_err(dev->dev, "GTT new %p, %d\n", gt, gt->stolen);
return gt; return gt;
} }
kfree(gt); kfree(gt);
...@@ -340,6 +341,7 @@ static void psb_gtt_destroy(struct kref *kref) ...@@ -340,6 +341,7 @@ static void psb_gtt_destroy(struct kref *kref)
} }
WARN_ON(gt->in_gart && !gt->stolen); WARN_ON(gt->in_gart && !gt->stolen);
release_resource(&gt->resource); release_resource(&gt->resource);
pr_err("GTT destroyed %p, %d\n", gt, gt->stolen);
kfree(gt); kfree(gt);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment