From 5fdfbee22acb8eaaa834457c30e6f68883ab1353 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 23 Sep 2008 16:47:34 +1000 Subject: [PATCH] Store the buffer object backing the fb as a void pointer, not a handle. This lets us defer handle creation until userspace acutally asks for one, at which point we also have a drm_file to associate it with. --- linux-core/atombios_crtc.c | 4 +++- linux-core/drm_crtc.c | 2 +- linux-core/drm_crtc.h | 5 ++++- linux-core/drm_crtc_helper.c | 5 +++-- linux-core/drm_crtc_helper.h | 3 ++- linux-core/radeon_display.c | 42 ++++++++++++++++++++++++++--------------- linux-core/radeon_fb.c | 6 ++---- linux-core/radeon_legacy_crtc.c | 8 ++++++-- linux-core/radeon_mode.h | 7 +++---- linux-core/radeon_pm.c | 9 +++++---- 10 files changed, 56 insertions(+), 35 deletions(-) diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c index cefe922..16bcbe8 100644 --- a/linux-core/atombios_crtc.c +++ b/linux-core/atombios_crtc.c @@ -244,6 +244,7 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y) struct drm_device *dev = crtc->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_framebuffer *radeon_fb; + struct drm_gem_object *obj; struct drm_radeon_gem_object *obj_priv; uint32_t fb_location, fb_format, fb_pitch_pixels; @@ -252,7 +253,8 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj_priv = radeon_fb->obj->driver_private; + obj = radeon_fb->base.mm_private; + obj_priv = obj->driver_private; fb_location = obj_priv->bo->offset + dev_priv->fb_location; diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index aa6749d..2fefd1d 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1631,8 +1631,8 @@ int drm_mode_getfb(struct drm_device *dev, r->width = fb->width; r->depth = fb->depth; r->bpp = fb->bits_per_pixel; - r->handle = fb->mm_handle; r->pitch = fb->pitch; + fb->funcs->create_handle(fb, file_priv, &r->handle); out: mutex_unlock(&dev->mode_config.mutex); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 5f63dc2..6a73a71 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -220,6 +220,9 @@ struct drm_display_info { struct drm_framebuffer_funcs { void (*destroy)(struct drm_framebuffer *framebuffer); + int (*create_handle)(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle); }; struct drm_framebuffer { @@ -237,7 +240,7 @@ struct drm_framebuffer { void *fbdev; u32 pseudo_palette[17]; struct list_head filp_head; - uint32_t mm_handle; + void *mm_private; }; struct drm_property_blob { diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c index b507315..b334f5b 100644 --- a/linux-core/drm_crtc_helper.c +++ b/linux-core/drm_crtc_helper.c @@ -771,14 +771,15 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev) EXPORT_SYMBOL(drm_helper_hotplug_stage_two); int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd) + struct drm_mode_fb_cmd *mode_cmd, + void *mm_private) { fb->width = mode_cmd->width; fb->height = mode_cmd->height; fb->pitch = mode_cmd->pitch; fb->bits_per_pixel = mode_cmd->bpp; fb->depth = mode_cmd->depth; - fb->mm_handle = mode_cmd->handle; + fb->mm_private = mm_private; return 0; } diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h index c071915..01b1423 100644 --- a/linux-core/drm_crtc_helper.h +++ b/linux-core/drm_crtc_helper.h @@ -75,7 +75,8 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_m extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd); + struct drm_mode_fb_cmd *mode_cmd, + void *mm_private); static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs) { diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index e2d02be..e8d141e 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -605,15 +605,25 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) kfree(radeon_fb); } +static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle) +{ + struct drm_gem_object *object = fb->mm_private; + + return drm_gem_handle_create(file_priv, object, handle); +} + static const struct drm_framebuffer_funcs radeon_fb_funcs = { .destroy = radeon_user_framebuffer_destroy, + .create_handle = radeon_user_framebuffer_create_handle, }; -struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - struct drm_mode_fb_cmd *mode_cmd) +struct drm_framebuffer * +radeon_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd *mode_cmd, + void *mm_private) { - struct radeon_framebuffer *radeon_fb; radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); @@ -621,20 +631,22 @@ struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev, return NULL; drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs); - drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd); - - if (filp) { - radeon_fb->obj = drm_gem_object_lookup(dev, filp, - mode_cmd->handle); - if (!radeon_fb->obj) { - kfree(radeon_fb); - return NULL; - } - drm_gem_object_unreference(radeon_fb->obj); - } + drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd, mm_private); return &radeon_fb->base; } +static struct drm_framebuffer * +radeon_user_framebuffer_create(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_mode_fb_cmd *mode_cmd) +{ + struct radeon_framebuffer *radeon_fb; + void *mm_private; + + mm_private = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); + return radeon_framebuffer_create(dev, mode_cmd, mm_private); +} + static const struct drm_mode_config_funcs radeon_mode_funcs = { .fb_create = radeon_user_framebuffer_create, .fb_changed = radeonfb_probe, diff --git a/linux-core/radeon_fb.c b/linux-core/radeon_fb.c index 8645967..8c9461d 100644 --- a/linux-core/radeon_fb.c +++ b/linux-core/radeon_fb.c @@ -744,7 +744,7 @@ int radeonfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_heigh } mutex_lock(&dev->struct_mutex); - fb = radeon_user_framebuffer_create(dev, NULL, &mode_cmd); + fb = radeon_framebuffer_create(dev, &mode_cmd, fbo); if (!fb) { DRM_ERROR("failed to allocate fb.\n"); ret = -ENOMEM; @@ -756,8 +756,6 @@ int radeonfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_heigh radeon_fb = to_radeon_framebuffer(fb); *radeon_fb_p = radeon_fb; - radeon_fb->obj = fbo; - info = framebuffer_alloc(sizeof(struct radeonfb_par), device); if (!info) { ret = -ENOMEM; @@ -1150,7 +1148,7 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) unregister_framebuffer(info); drm_bo_kunmap(&radeon_fb->kmap_obj); mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(radeon_fb->obj); + drm_gem_object_unreference(fb->mm_private); mutex_unlock(&dev->struct_mutex); framebuffer_release(info); } diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c index d51fc52..bc28c43 100644 --- a/linux-core/radeon_legacy_crtc.c +++ b/linux-core/radeon_legacy_crtc.c @@ -176,6 +176,7 @@ static bool radeon_set_crtc1_base(struct drm_crtc *crtc, int x, int y) struct drm_device *dev = crtc->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_framebuffer *radeon_fb; + struct drm_gem_object *obj; struct drm_radeon_gem_object *obj_priv; uint32_t base; uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; @@ -185,7 +186,8 @@ static bool radeon_set_crtc1_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj_priv = radeon_fb->obj->driver_private; + obj = radeon_fb->base.mm_private; + obj_priv = obj->driver_private; crtc_offset = obj_priv->bo->offset; @@ -599,6 +601,7 @@ static bool radeon_set_crtc2_base(struct drm_crtc *crtc, int x, int y) struct drm_device *dev = crtc->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_framebuffer *radeon_fb; + struct drm_gem_object *obj; struct drm_radeon_gem_object *obj_priv; uint32_t base; uint32_t crtc2_offset, crtc2_offset_cntl, crtc2_tile_x0_y0 = 0; @@ -608,7 +611,8 @@ static bool radeon_set_crtc2_base(struct drm_crtc *crtc, int x, int y) radeon_fb = to_radeon_framebuffer(crtc->fb); - obj_priv = radeon_fb->obj->driver_private; + obj = radeon_fb->base.mm_private; + obj_priv = obj->driver_private; crtc2_offset = obj_priv->bo->offset; diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index d4b33dd..577c3cf 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -248,7 +248,6 @@ struct radeon_connector { struct radeon_framebuffer { struct drm_framebuffer base; - struct drm_gem_object *obj; struct drm_bo_kmap_obj kmap_obj; }; @@ -313,9 +312,9 @@ extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev); extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); -struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - struct drm_mode_fb_cmd *mode_cmd); +struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, + struct drm_mode_fb_cmd *mode_cmd, + void *mm_private); int radeonfb_probe(struct drm_device *dev); diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c index 5d14384..de10779 100644 --- a/linux-core/radeon_pm.c +++ b/linux-core/radeon_pm.c @@ -54,10 +54,10 @@ int radeon_suspend(struct drm_device *dev, pm_message_t state) if (!radeon_fb) continue; - if (!radeon_fb->obj) + if (!radeon_fb->base.mm_private) continue; - radeon_gem_object_unpin(radeon_fb->obj); + radeon_gem_object_unpin(radeon_fb->base.mm_private); } if (!(dev_priv->flags & RADEON_IS_IGP)) @@ -168,10 +168,11 @@ int radeon_resume(struct drm_device *dev) if (!radeon_fb) continue; - if (!radeon_fb->obj) + if (!radeon_fb->base.mm_private) continue; - radeon_gem_object_pin(radeon_fb->obj, PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM); + radeon_gem_object_pin(radeon_fb->base.mm_private, + PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM); } /* blat the mode back in */ drm_helper_resume_force_mode(dev); -- 2.7.4