2009/7/28 Michel Dänzer <mic...@daenzer.net>:
> From: Michel Dänzer <daen...@vmware.com>
>
> Just use the fb_mmap hook. KMS will pin when necessary. This way we aren't
> wasting precious VRAM when we're e.g. in X.
>
> This means fbdev userspace will only be able to map the framebuffer via
> /dev/fb*, not via /dev/mem, but that's hardly a loss.

This doesn't take into account the kmapped copy we use for fbcon. You
can't evict this object while there is a kmap held on it, since it directly
maps the VRAM pages using ioremap.

Dave.

>
> Signed-off-by: Michel Dänzer <daen...@vmware.com>
> ---
>  drivers/gpu/drm/radeon/radeon.h        |    2 --
>  drivers/gpu/drm/radeon/radeon_device.c |    4 +---
>  drivers/gpu/drm/radeon/radeon_fb.c     |   24 +++++++++++-------------
>  3 files changed, 12 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 3cd43ce..f5b7800 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -600,8 +600,6 @@ struct radeon_device {
>        uint16_t                        bios_header_start;
>        struct radeon_object            *stollen_vga_memory;
>        struct fb_info                  *fbdev_info;
> -       struct radeon_object            *fbdev_robj;
> -       struct radeon_framebuffer       *fbdev_rfb;
>        /* Register mmio */
>        unsigned long                   rmmio_base;
>        unsigned long                   rmmio_size;
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
> b/drivers/gpu/drm/radeon/radeon_device.c
> index a03eebd..a2418d4 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -705,9 +705,7 @@ int radeon_suspend_kms(struct drm_device *dev, 
> pm_message_t state)
>                        continue;
>                }
>                robj = rfb->obj->driver_private;
> -               if (robj != rdev->fbdev_robj) {
> -                       radeon_object_unpin(robj);
> -               }
> +               radeon_object_unpin(robj);
>        }
>        /* evict vram memory */
>        radeon_object_evict_vram(rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_fb.c 
> b/drivers/gpu/drm/radeon/radeon_fb.c
> index 260870a..9c57c15 100644
> --- a/drivers/gpu/drm/radeon/radeon_fb.c
> +++ b/drivers/gpu/drm/radeon/radeon_fb.c
> @@ -49,6 +49,7 @@ struct radeon_fb_device {
>        struct radeon_device            *rdev;
>        struct drm_display_mode         *mode;
>        struct radeon_framebuffer       *rfb;
> +       struct radeon_object            *robj;
>        int                             crtc_count;
>        /* crtc currently bound to this */
>        uint32_t                        crtc_ids[2];
> @@ -404,6 +405,14 @@ int radeonfb_blank(int blank, struct fb_info *info)
>        return 0;
>  }
>
> +static int radeonfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
> +{
> +       struct radeon_fb_device *rfbdev = info->par;
> +       struct radeon_object *robj = rfbdev->rfb->obj->driver_private;
> +
> +       return radeon_object_fbdev_mmap(robj, vma);
> +}
> +
>  static struct fb_ops radeonfb_ops = {
>        .owner = THIS_MODULE,
>        .fb_check_var = radeonfb_check_var,
> @@ -414,6 +423,7 @@ static struct fb_ops radeonfb_ops = {
>        .fb_imageblit = cfb_imageblit,
>        .fb_pan_display = radeonfb_pan_display,
>        .fb_blank = radeonfb_blank,
> +       .fb_mmap = radeonfb_mmap,
>  };
>
>  /**
> @@ -509,9 +519,7 @@ int radeonfb_create(struct radeon_device *rdev,
>        struct radeon_object *robj = NULL;
>        struct device *device = &rdev->pdev->dev;
>        int size, aligned_size, ret;
> -       u64 fb_gpuaddr;
>        void *fbptr = NULL;
> -       unsigned long tmp;
>
>        mode_cmd.width = surface_width;
>        mode_cmd.height = surface_height;
> @@ -542,19 +550,11 @@ int radeonfb_create(struct radeon_device *rdev,
>                ret = -ENOMEM;
>                goto out_unref;
>        }
> -       ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
> -       if (ret) {
> -               printk(KERN_ERR "failed to pin framebuffer\n");
> -               ret = -ENOMEM;
> -               goto out_unref;
> -       }
>
>        list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list);
>
>        rfb = to_radeon_framebuffer(fb);
>        *rfb_p = rfb;
> -       rdev->fbdev_rfb = rfb;
> -       rdev->fbdev_robj = robj;
>
>        info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
>        if (info == NULL) {
> @@ -580,8 +580,7 @@ int radeonfb_create(struct radeon_device *rdev,
>        info->flags = FBINFO_DEFAULT;
>        info->fbops = &radeonfb_ops;
>        info->fix.line_length = fb->pitch;
> -       tmp = fb_gpuaddr - rdev->mc.vram_location;
> -       info->fix.smem_start = rdev->mc.aper_base + tmp;
> +       info->fix.smem_start = ~0;
>        info->fix.smem_len = size;
>        info->screen_base = fbptr;
>        info->screen_size = size;
> @@ -870,7 +869,6 @@ int radeonfb_remove(struct drm_device *dev, struct 
> drm_framebuffer *fb)
>                robj = rfb->obj->driver_private;
>                unregister_framebuffer(info);
>                radeon_object_kunmap(robj);
> -               radeon_object_unpin(robj);
>                framebuffer_release(info);
>        }
>
> --
> 1.6.3.1
>
>

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to