Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 259657
b: refs/heads/master
c: daab23f
h: refs/heads/master
i:
  259655: cea8a4b
v: v3
  • Loading branch information
Alan Cox authored and Greg Kroah-Hartman committed Jul 5, 2011
1 parent 2062838 commit 63d2e0a
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 98 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9460e84a91451e57ba823037be483ecbfdd9cd44
refs/heads/master: daab23f1f52bba4701f58b79855f1ad0cf523dca
13 changes: 3 additions & 10 deletions trunk/drivers/staging/gma500/psb_2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static void psbfb_fillrect_accel(struct fb_info *info,
const struct fb_fillrect *r)
{
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_framebuffer *fb = fbdev->psb_fb_helper.fb;
struct drm_psb_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -291,7 +291,7 @@ static void psbfb_copyarea_accel(struct fb_info *info,
const struct fb_copyarea *a)
{
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_framebuffer *fb = fbdev->psb_fb_helper.fb;
struct drm_psb_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -360,19 +360,12 @@ void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
int psbfb_sync(struct fb_info *info)
{
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_psb_private *dev_priv = dev->dev_private;
unsigned long _end = jiffies + DRM_HZ;
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.
*/
Expand Down
195 changes: 110 additions & 85 deletions trunk/drivers/staging/gma500/psb_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ static struct vm_operations_struct psbfb_vm_ops = {
static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct psb_fbdev *fbdev = info->par;
struct psb_framebuffer *psbfb = fbdev->pfb;
struct psb_framebuffer *psbfb = &fbdev->pfb;
char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -267,7 +267,7 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
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_psb_private *dev_priv = dev->dev_private;
u32 __user *p = (u32 __user *)arg;
Expand Down Expand Up @@ -304,31 +304,73 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl,
};

/**
* psb_framebuffer_init - initialize a framebuffer
* @dev: our DRM device
* @fb: framebuffer to set up
* @mode_cmd: mode description
* @gt: backing object
*
* Configure and fill in the boilerplate for our frame buffer. Return
* 0 on success or an error code if we fail.
*/
static int psb_framebuffer_init(struct drm_device *dev,
struct psb_framebuffer *fb,
struct drm_mode_fb_cmd *mode_cmd,
struct gtt_range *gt)
{
int ret;

if (mode_cmd->pitch & 63)
return -EINVAL;
switch (mode_cmd->bpp) {
case 8:
case 16:
case 24:
case 32:
break;
default:
return -EINVAL;
}
ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
if (ret) {
dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
return ret;
}
drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
fb->gtt = gt;
return 0;
}

/**
* psb_framebuffer_create - create a framebuffer backed by gt
* @dev: our DRM device
* @mode_cmd: the description of the requested mode
* @gt: the backing object
*
* Create a framebuffer object backed by the gt, and fill in the
* boilerplate required
*
* TODO: review object references
*/
static struct drm_framebuffer *psb_framebuffer_create
(struct drm_device *dev, struct drm_mode_fb_cmd *r,
(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
struct gtt_range *gt)
{
struct psb_framebuffer *fb;
int ret;

fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return NULL;

ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);

if (ret)
goto err;

drm_helper_mode_fill_fb_struct(&fb->base, r);

fb->gtt = gt;

return &fb->base;
return ERR_PTR(-ENOMEM);

err:
kfree(fb);
return NULL;
ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
if (ret) {
kfree(fb);
return ERR_PTR(ret);
}
return &fb->base;
}

/**
Expand Down Expand Up @@ -380,56 +422,63 @@ static int psbfb_create(struct psb_fbdev *fbdev,
struct drm_psb_private *dev_priv = dev->dev_private;
struct fb_info *info;
struct drm_framebuffer *fb;
struct psb_framebuffer *psbfb;
struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_mode_fb_cmd mode_cmd;
struct device *device = &dev->pdev->dev;
int size, aligned_size;
int size;
int ret;
struct gtt_range *backing;

mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
mode_cmd.bpp = sizes->surface_bpp;

/* No 24bit packed */
if (mode_cmd.bpp == 24)
mode_cmd.bpp = 32;

mode_cmd.bpp = 32;
/* HW requires pitch to be 64 byte aligned */
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
mode_cmd.depth = 24;
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
mode_cmd.depth = sizes->surface_depth;

size = mode_cmd.pitch * mode_cmd.height;
aligned_size = ALIGN(size, PAGE_SIZE);
size = ALIGN(size, PAGE_SIZE);

/* Allocate the framebuffer in the GTT with stolen page backing */
backing = psbfb_alloc(dev, aligned_size);
backing = psbfb_alloc(dev, size);
if (backing == NULL)
return -ENOMEM;

mutex_lock(&dev->struct_mutex);
fb = psb_framebuffer_create(dev, &mode_cmd, backing);
if (!fb) {
DRM_ERROR("failed to allocate fb.\n");
ret = -ENOMEM;
goto out_err1;
}
psbfb = to_psb_fb(fb);

info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
info = framebuffer_alloc(0, device);
if (!info) {
ret = -ENOMEM;
goto out_err0;
goto out_err1;
}

info->par = fbdev;

ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
if (ret)
goto out_unref;

fb = &psbfb->base;
psbfb->fbdev = info;

fbdev->psb_fb_helper.fb = fb;
fbdev->psb_fb_helper.fbdev = info;
fbdev->pfb = psbfb;

strcpy(info->fix.id, "psbfb");

info->flags = FBINFO_DEFAULT;
info->fbops = &psbfb_ops;

ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
ret = -ENOMEM;
goto out_unref;
}

info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;

Expand All @@ -445,18 +494,18 @@ static int psbfb_create(struct psb_fbdev *fbdev,
if (info->screen_base == NULL) {
psb_gtt_unpin(backing);
ret = -ENOMEM;
goto out_err0;
goto out_unref;
}
psbfb->vm_map = 1;
}
info->screen_size = size;
memset(info->screen_base, 0, size);
/* memset(info->screen_base, 0, size); */

if (dev_priv->pg->stolen_size) {
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
goto out_err0;
goto out_unref;
}
info->apertures->ranges[0].base = dev->mode_config.fb_base;
info->apertures->ranges[0].size = dev_priv->pg->stolen_size;
Expand Down Expand Up @@ -484,8 +533,14 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_unlock(&dev->struct_mutex);

return 0;
out_err0:
fb->funcs->destroy(fb);
out_unref:
if (backing->stolen)
psb_gtt_free_range(dev, backing);
else {
if (psbfb->vm_map)
vm_unmap_ram(info->screen_base, backing->npage);
drm_gem_object_unreference(&backing->gem);
}
out_err1:
mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing);
Expand All @@ -506,31 +561,16 @@ static struct drm_framebuffer *psb_user_framebuffer_create
{
struct gtt_range *r;
struct drm_gem_object *obj;
struct psb_framebuffer *psbfb;

/* Find the GEM object and thus the gtt range object that is
to back this space */
obj = drm_gem_object_lookup(dev, filp, cmd->handle);
if (obj == NULL)
return ERR_PTR(-ENOENT);

/* Allocate a framebuffer */
psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL);
if (psbfb == NULL) {
drm_gem_object_unreference_unlocked(obj);
return ERR_PTR(-ENOMEM);
}

/* Let the core code do all the work */
r = container_of(obj, struct gtt_range, gem);
if (psb_framebuffer_create(dev, cmd, r) == NULL) {
drm_gem_object_unreference_unlocked(obj);
kfree(psbfb);
return ERR_PTR(-EINVAL);
}
/* Return the drm_framebuffer contained within the psb fbdev which
has been initialized by the framebuffer creation */
return &psbfb->base;
return psb_framebuffer_create(dev, cmd, r);
}

static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
Expand Down Expand Up @@ -572,7 +612,7 @@ struct drm_fb_helper_funcs psb_fb_helper_funcs = {
int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
{
struct fb_info *info;
struct psb_framebuffer *psbfb = fbdev->pfb;
struct psb_framebuffer *psbfb = &fbdev->pfb;

if (fbdev->psb_fb_helper.fbdev) {
info = fbdev->psb_fb_helper.fbdev;
Expand All @@ -583,20 +623,23 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
psb_gtt_unpin(psbfb->gtt);
}
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_fini(&fbdev->psb_fb_helper);
drm_framebuffer_cleanup(&psbfb->base);

if (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 */
if (psbfb->gtt->stolen)
psb_gtt_free_range(dev, psbfb->gtt);
else
drm_gem_object_unreference(&psbfb->gtt->gem);
unregister_framebuffer(info);
iounmap(info->screen_base);
framebuffer_release(info);
}

drm_fb_helper_fini(&fbdev->psb_fb_helper);
drm_framebuffer_cleanup(&psbfb->base);
}
return 0;
}

Expand Down Expand Up @@ -644,22 +687,6 @@ static void psbfb_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
}

int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
{
struct fb_info *info;
struct psb_framebuffer *psbfb = to_psb_fb(fb);

if (drm_psb_no_fb)
return 0;

info = psbfb->fbdev;

if (info)
framebuffer_release(info);
return 0;
}
/*EXPORT_SYMBOL(psbfb_remove); */

/**
* psb_user_framebuffer_create_handle - add hamdle to a framebuffer
* @fb: framebuffer
Expand Down Expand Up @@ -690,15 +717,13 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
*/
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

/* Should never get stolen memory for a user fb */
WARN_ON(r->stolen);
pr_err("user framebuffer destroy %p, fbdev %p\n",
psbfb, psbfb->fbdev);
if (psbfb->fbdev)
psbfb_remove(dev, fb);

/* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
/* We are no longer using the resource in GEM */
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/staging/gma500/psb_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct psb_framebuffer {

struct psb_fbdev {
struct drm_fb_helper psb_fb_helper;
struct psb_framebuffer *pfb;
struct psb_framebuffer pfb;
};


Expand Down
Loading

0 comments on commit 63d2e0a

Please sign in to comment.