aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-03-30 01:34:13 -0400
committerDave Airlie <airlied@redhat.com>2010-04-06 20:21:03 -0400
commit386516744ba45d50f42c6999151cc210cb4f96e4 (patch)
tree88e3b6aeb83040a8bd512eb7aad087e6c0fcd556 /drivers/gpu/drm/radeon
parent643acacf02679befd0f98ac3c5fecb805f1c9548 (diff)
drm/fb: fix fbdev object model + cleanup properly.
The fbdev layer in the kms code should act like a consumer of the kms services and avoid having relying on information being store in the kms core structures in order for it to work. This patch a) removes the info pointer/psuedo palette from the core drm_framebuffer structure and moves it to the fbdev helper layer, it also removes the core drm keeping a list of kernel kms fbdevs. b) migrated all the fb helper functions out of the crtc helper file into the fb helper file. c) pushed the fb probing/hotplug control into the driver d) makes the surface sizes into a structure for ease of passing This changes the intel/radeon/nouveau drivers to use the new helper. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c42
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c220
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h23
7 files changed, 169 insertions, 133 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 034218c3dbbb..4f50807ae0a5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -927,9 +927,6 @@ struct radeon_device {
927 bool is_atom_bios; 927 bool is_atom_bios;
928 uint16_t bios_header_start; 928 uint16_t bios_header_start;
929 struct radeon_bo *stollen_vga_memory; 929 struct radeon_bo *stollen_vga_memory;
930 struct fb_info *fbdev_info;
931 struct radeon_bo *fbdev_rbo;
932 struct radeon_framebuffer *fbdev_rfb;
933 /* Register mmio */ 930 /* Register mmio */
934 resource_size_t rmmio_base; 931 resource_size_t rmmio_base;
935 resource_size_t rmmio_size; 932 resource_size_t rmmio_size;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 60ec47b71642..90e8883494ad 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -676,9 +676,10 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
676 continue; 676 continue;
677 } 677 }
678 robj = rfb->obj->driver_private; 678 robj = rfb->obj->driver_private;
679 if (robj != rdev->fbdev_rbo) { 679 /* don't unpin kernel fb objects */
680 if (!radeon_fbdev_robj_is_fb(rdev, robj)) {
680 r = radeon_bo_reserve(robj, false); 681 r = radeon_bo_reserve(robj, false);
681 if (unlikely(r == 0)) { 682 if (r == 0) {
682 radeon_bo_unpin(robj); 683 radeon_bo_unpin(robj);
683 radeon_bo_unreserve(robj); 684 radeon_bo_unreserve(robj);
684 } 685 }
@@ -703,7 +704,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
703 pci_set_power_state(dev->pdev, PCI_D3hot); 704 pci_set_power_state(dev->pdev, PCI_D3hot);
704 } 705 }
705 acquire_console_sem(); 706 acquire_console_sem();
706 fb_set_suspend(rdev->fbdev_info, 1); 707 radeon_fbdev_set_suspend(rdev, 1);
707 release_console_sem(); 708 release_console_sem();
708 return 0; 709 return 0;
709} 710}
@@ -727,7 +728,7 @@ int radeon_resume_kms(struct drm_device *dev)
727 radeon_agp_resume(rdev); 728 radeon_agp_resume(rdev);
728 radeon_resume(rdev); 729 radeon_resume(rdev);
729 radeon_restore_bios_scratch_regs(rdev); 730 radeon_restore_bios_scratch_regs(rdev);
730 fb_set_suspend(rdev->fbdev_info, 0); 731 radeon_fbdev_set_suspend(rdev, 0);
731 release_console_sem(); 732 release_console_sem();
732 733
733 /* reset hpd state */ 734 /* reset hpd state */
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index b8d672828246..243c1c4bc836 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -831,10 +831,6 @@ void radeon_compute_pll(struct radeon_pll *pll,
831static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) 831static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
832{ 832{
833 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 833 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
834 struct drm_device *dev = fb->dev;
835
836 if (fb->fbdev)
837 radeonfb_remove(dev, fb);
838 834
839 if (radeon_fb->obj) 835 if (radeon_fb->obj)
840 drm_gem_object_unreference_unlocked(radeon_fb->obj); 836 drm_gem_object_unreference_unlocked(radeon_fb->obj);
@@ -856,21 +852,15 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
856 .create_handle = radeon_user_framebuffer_create_handle, 852 .create_handle = radeon_user_framebuffer_create_handle,
857}; 853};
858 854
859struct drm_framebuffer * 855void
860radeon_framebuffer_create(struct drm_device *dev, 856radeon_framebuffer_init(struct drm_device *dev,
861 struct drm_mode_fb_cmd *mode_cmd, 857 struct radeon_framebuffer *rfb,
862 struct drm_gem_object *obj) 858 struct drm_mode_fb_cmd *mode_cmd,
859 struct drm_gem_object *obj)
863{ 860{
864 struct radeon_framebuffer *radeon_fb; 861 rfb->obj = obj;
865 862 drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
866 radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); 863 drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
867 if (radeon_fb == NULL) {
868 return NULL;
869 }
870 drm_framebuffer_init(dev, &radeon_fb->base, &radeon_fb_funcs);
871 drm_helper_mode_fill_fb_struct(&radeon_fb->base, mode_cmd);
872 radeon_fb->obj = obj;
873 return &radeon_fb->base;
874} 864}
875 865
876static struct drm_framebuffer * 866static struct drm_framebuffer *
@@ -879,6 +869,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
879 struct drm_mode_fb_cmd *mode_cmd) 869 struct drm_mode_fb_cmd *mode_cmd)
880{ 870{
881 struct drm_gem_object *obj; 871 struct drm_gem_object *obj;
872 struct radeon_framebuffer *radeon_fb;
882 873
883 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 874 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
884 if (obj == NULL) { 875 if (obj == NULL) {
@@ -886,12 +877,19 @@ radeon_user_framebuffer_create(struct drm_device *dev,
886 "can't create framebuffer\n", mode_cmd->handle); 877 "can't create framebuffer\n", mode_cmd->handle);
887 return NULL; 878 return NULL;
888 } 879 }
889 return radeon_framebuffer_create(dev, mode_cmd, obj); 880
881 radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
882 if (radeon_fb == NULL) {
883 return NULL;
884 }
885
886 radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
887
888 return &radeon_fb->base;
890} 889}
891 890
892static const struct drm_mode_config_funcs radeon_mode_funcs = { 891static const struct drm_mode_config_funcs radeon_mode_funcs = {
893 .fb_create = radeon_user_framebuffer_create, 892 .fb_create = radeon_user_framebuffer_create,
894 .fb_changed = radeonfb_probe,
895}; 893};
896 894
897struct drm_prop_enum_list { 895struct drm_prop_enum_list {
@@ -1031,12 +1029,14 @@ int radeon_modeset_init(struct radeon_device *rdev)
1031 } 1029 }
1032 /* initialize hpd */ 1030 /* initialize hpd */
1033 radeon_hpd_init(rdev); 1031 radeon_hpd_init(rdev);
1034 drm_helper_initial_config(rdev->ddev); 1032
1033 radeon_fbdev_init(rdev);
1035 return 0; 1034 return 0;
1036} 1035}
1037 1036
1038void radeon_modeset_fini(struct radeon_device *rdev) 1037void radeon_modeset_fini(struct radeon_device *rdev)
1039{ 1038{
1039 radeon_fbdev_fini(rdev);
1040 kfree(rdev->mode_info.bios_hardcoded_edid); 1040 kfree(rdev->mode_info.bios_hardcoded_edid);
1041 1041
1042 if (rdev->mode_info.mode_config_initialized) { 1042 if (rdev->mode_info.mode_config_initialized) {
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 8fccbf29235e..a7e4c2a89ee0 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -41,10 +41,15 @@
41 41
42#include <linux/vga_switcheroo.h> 42#include <linux/vga_switcheroo.h>
43 43
44struct radeon_fb_device { 44/* object hierarchy -
45 this contains a helper + a radeon fb
46 the helper contains a pointer to radeon framebuffer baseclass.
47*/
48struct radeon_kernel_fbdev {
45 struct drm_fb_helper helper; 49 struct drm_fb_helper helper;
46 struct radeon_framebuffer *rfb; 50 struct radeon_framebuffer rfb;
47 struct radeon_device *rdev; 51 struct list_head fbdev_list;
52 struct radeon_device *rdev;
48}; 53};
49 54
50static struct fb_ops radeonfb_ops = { 55static struct fb_ops radeonfb_ops = {
@@ -60,45 +65,6 @@ static struct fb_ops radeonfb_ops = {
60 .fb_setcmap = drm_fb_helper_setcmap, 65 .fb_setcmap = drm_fb_helper_setcmap,
61}; 66};
62 67
63/**
64 * Currently it is assumed that the old framebuffer is reused.
65 *
66 * LOCKING
67 * caller should hold the mode config lock.
68 *
69 */
70int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
71{
72 struct fb_info *info;
73 struct drm_framebuffer *fb;
74 struct drm_display_mode *mode = crtc->desired_mode;
75
76 fb = crtc->fb;
77 if (fb == NULL) {
78 return 1;
79 }
80 info = fb->fbdev;
81 if (info == NULL) {
82 return 1;
83 }
84 if (mode == NULL) {
85 return 1;
86 }
87 info->var.xres = mode->hdisplay;
88 info->var.right_margin = mode->hsync_start - mode->hdisplay;
89 info->var.hsync_len = mode->hsync_end - mode->hsync_start;
90 info->var.left_margin = mode->htotal - mode->hsync_end;
91 info->var.yres = mode->vdisplay;
92 info->var.lower_margin = mode->vsync_start - mode->vdisplay;
93 info->var.vsync_len = mode->vsync_end - mode->vsync_start;
94 info->var.upper_margin = mode->vtotal - mode->vsync_end;
95 info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
96 /* avoid overflow */
97 info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
98
99 return 0;
100}
101EXPORT_SYMBOL(radeonfb_resize);
102 68
103static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) 69static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
104{ 70{
@@ -129,17 +95,14 @@ static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
129 .gamma_get = radeon_crtc_fb_gamma_get, 95 .gamma_get = radeon_crtc_fb_gamma_get,
130}; 96};
131 97
132int radeonfb_create(struct drm_device *dev, 98static int radeonfb_create(struct drm_device *dev,
133 uint32_t fb_width, uint32_t fb_height, 99 struct drm_fb_helper_surface_size *sizes,
134 uint32_t surface_width, uint32_t surface_height, 100 struct radeon_kernel_fbdev **rfbdev_p)
135 uint32_t surface_depth, uint32_t surface_bpp,
136 struct drm_framebuffer **fb_p)
137{ 101{
138 struct radeon_device *rdev = dev->dev_private; 102 struct radeon_device *rdev = dev->dev_private;
139 struct fb_info *info; 103 struct fb_info *info;
140 struct radeon_fb_device *rfbdev; 104 struct radeon_kernel_fbdev *rfbdev;
141 struct drm_framebuffer *fb = NULL; 105 struct drm_framebuffer *fb = NULL;
142 struct radeon_framebuffer *rfb;
143 struct drm_mode_fb_cmd mode_cmd; 106 struct drm_mode_fb_cmd mode_cmd;
144 struct drm_gem_object *gobj = NULL; 107 struct drm_gem_object *gobj = NULL;
145 struct radeon_bo *rbo = NULL; 108 struct radeon_bo *rbo = NULL;
@@ -151,17 +114,17 @@ int radeonfb_create(struct drm_device *dev,
151 bool fb_tiled = false; /* useful for testing */ 114 bool fb_tiled = false; /* useful for testing */
152 u32 tiling_flags = 0; 115 u32 tiling_flags = 0;
153 116
154 mode_cmd.width = surface_width; 117 mode_cmd.width = sizes->surface_width;
155 mode_cmd.height = surface_height; 118 mode_cmd.height = sizes->surface_height;
156 119
157 /* avivo can't scanout real 24bpp */ 120 /* avivo can't scanout real 24bpp */
158 if ((surface_bpp == 24) && ASIC_IS_AVIVO(rdev)) 121 if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
159 surface_bpp = 32; 122 sizes->surface_bpp = 32;
160 123
161 mode_cmd.bpp = surface_bpp; 124 mode_cmd.bpp = sizes->surface_bpp;
162 /* need to align pitch with crtc limits */ 125 /* need to align pitch with crtc limits */
163 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); 126 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
164 mode_cmd.depth = surface_depth; 127 mode_cmd.depth = sizes->surface_depth;
165 128
166 size = mode_cmd.pitch * mode_cmd.height; 129 size = mode_cmd.pitch * mode_cmd.height;
167 aligned_size = ALIGN(size, PAGE_SIZE); 130 aligned_size = ALIGN(size, PAGE_SIZE);
@@ -172,7 +135,7 @@ int radeonfb_create(struct drm_device *dev,
172 &gobj); 135 &gobj);
173 if (ret) { 136 if (ret) {
174 printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", 137 printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
175 surface_width, surface_height); 138 sizes->surface_width, sizes->surface_height);
176 ret = -ENOMEM; 139 ret = -ENOMEM;
177 goto out; 140 goto out;
178 } 141 }
@@ -201,12 +164,7 @@ int radeonfb_create(struct drm_device *dev,
201 dev_err(rdev->dev, "FB failed to set tiling flags\n"); 164 dev_err(rdev->dev, "FB failed to set tiling flags\n");
202 } 165 }
203 mutex_lock(&rdev->ddev->struct_mutex); 166 mutex_lock(&rdev->ddev->struct_mutex);
204 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); 167
205 if (fb == NULL) {
206 DRM_ERROR("failed to allocate fb.\n");
207 ret = -ENOMEM;
208 goto out_unref;
209 }
210 ret = radeon_bo_reserve(rbo, false); 168 ret = radeon_bo_reserve(rbo, false);
211 if (unlikely(ret != 0)) 169 if (unlikely(ret != 0))
212 goto out_unref; 170 goto out_unref;
@@ -223,23 +181,25 @@ int radeonfb_create(struct drm_device *dev,
223 goto out_unref; 181 goto out_unref;
224 } 182 }
225 183
226 list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); 184 info = framebuffer_alloc(sizeof(struct radeon_kernel_fbdev), device);
227
228 *fb_p = fb;
229 rfb = to_radeon_framebuffer(fb);
230 rdev->fbdev_rfb = rfb;
231 rdev->fbdev_rbo = rbo;
232
233 info = framebuffer_alloc(sizeof(struct radeon_fb_device), device);
234 if (info == NULL) { 185 if (info == NULL) {
235 ret = -ENOMEM; 186 ret = -ENOMEM;
236 goto out_unref; 187 goto out_unref;
237 } 188 }
238 189
239 rdev->fbdev_info = info;
240 rfbdev = info->par; 190 rfbdev = info->par;
191 rfbdev->rdev = rdev;
192 radeon_framebuffer_init(dev, &rfbdev->rfb, &mode_cmd, gobj);
193 fb = &rfbdev->rfb.base;
194
195 /* setup helper */
196 rfbdev->helper.fb = fb;
197 rfbdev->helper.fbdev = info;
241 rfbdev->helper.funcs = &radeon_fb_helper_funcs; 198 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
242 rfbdev->helper.dev = dev; 199 rfbdev->helper.dev = dev;
200
201 *rfbdev_p = rfbdev;
202
243 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, rdev->num_crtc, 203 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, rdev->num_crtc,
244 RADEONFB_CONN_LIMIT); 204 RADEONFB_CONN_LIMIT);
245 if (ret) 205 if (ret)
@@ -260,7 +220,7 @@ int radeonfb_create(struct drm_device *dev,
260 info->screen_base = fbptr; 220 info->screen_base = fbptr;
261 info->screen_size = size; 221 info->screen_size = size;
262 222
263 drm_fb_helper_fill_var(info, fb, fb_width, fb_height); 223 drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
264 224
265 /* setup aperture base/size for vesafb takeover */ 225 /* setup aperture base/size for vesafb takeover */
266 info->aperture_base = rdev->ddev->mode_config.fb_base; 226 info->aperture_base = rdev->ddev->mode_config.fb_base;
@@ -283,9 +243,6 @@ int radeonfb_create(struct drm_device *dev,
283 DRM_INFO("fb depth is %d\n", fb->depth); 243 DRM_INFO("fb depth is %d\n", fb->depth);
284 DRM_INFO(" pitch is %d\n", fb->pitch); 244 DRM_INFO(" pitch is %d\n", fb->pitch);
285 245
286 fb->fbdev = info;
287 rfbdev->rfb = rfb;
288 rfbdev->rdev = rdev;
289 246
290 mutex_unlock(&rdev->ddev->struct_mutex); 247 mutex_unlock(&rdev->ddev->struct_mutex);
291 vga_switcheroo_client_fb_set(rdev->ddev->pdev, info); 248 vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
@@ -300,7 +257,6 @@ out_unref:
300 } 257 }
301 } 258 }
302 if (fb && ret) { 259 if (fb && ret) {
303 list_del(&fb->filp_head);
304 drm_gem_object_unreference(gobj); 260 drm_gem_object_unreference(gobj);
305 drm_framebuffer_cleanup(fb); 261 drm_framebuffer_cleanup(fb);
306 kfree(fb); 262 kfree(fb);
@@ -311,6 +267,35 @@ out:
311 return ret; 267 return ret;
312} 268}
313 269
270static int radeon_fb_find_or_create_single(struct drm_device *dev,
271 struct drm_fb_helper_surface_size *sizes,
272 struct drm_fb_helper **fb_ptr)
273{
274 struct radeon_device *rdev = dev->dev_private;
275 struct radeon_kernel_fbdev *rfbdev = NULL;
276 int new_fb = 0;
277 int ret;
278
279 if (!rdev->mode_info.rfbdev) {
280 ret = radeonfb_create(dev, sizes,
281 &rfbdev);
282 if (ret)
283 return ret;
284 rdev->mode_info.rfbdev = rfbdev;
285 new_fb = 1;
286 } else {
287 rfbdev = rdev->mode_info.rfbdev;
288 if (rfbdev->rfb.base.width < sizes->surface_width ||
289 rfbdev->rfb.base.height < sizes->surface_height) {
290 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
291 return -EINVAL;
292 }
293 }
294
295 *fb_ptr = &rfbdev->helper;
296 return new_fb;
297}
298
314static char *mode_option; 299static char *mode_option;
315int radeon_parse_options(char *options) 300int radeon_parse_options(char *options)
316{ 301{
@@ -327,7 +312,7 @@ int radeon_parse_options(char *options)
327 return 0; 312 return 0;
328} 313}
329 314
330int radeonfb_probe(struct drm_device *dev) 315static int radeonfb_probe(struct drm_device *dev)
331{ 316{
332 struct radeon_device *rdev = dev->dev_private; 317 struct radeon_device *rdev = dev->dev_private;
333 int bpp_sel = 32; 318 int bpp_sel = 32;
@@ -336,37 +321,76 @@ int radeonfb_probe(struct drm_device *dev)
336 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024)) 321 if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
337 bpp_sel = 8; 322 bpp_sel = 8;
338 323
339 return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeonfb_create); 324 return drm_fb_helper_single_fb_probe(dev, bpp_sel, &radeon_fb_find_or_create_single);
325}
326
327void radeonfb_hotplug(struct drm_device *dev)
328{
329 drm_helper_fb_hotplug_event(dev);
330
331 radeonfb_probe(dev);
340} 332}
341 333
342int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) 334static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_kernel_fbdev *rfbdev)
343{ 335{
344 struct fb_info *info; 336 struct fb_info *info;
345 struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb); 337 struct radeon_framebuffer *rfb = &rfbdev->rfb;
346 struct radeon_bo *rbo; 338 struct radeon_bo *rbo;
347 int r; 339 int r;
348 340
349 if (!fb) { 341 rbo = rfb->obj->driver_private;
350 return -EINVAL; 342 info = rfbdev->helper.fbdev;
351 } 343 unregister_framebuffer(info);
352 info = fb->fbdev; 344 r = radeon_bo_reserve(rbo, false);
353 if (info) { 345 if (likely(r == 0)) {
354 struct radeon_fb_device *rfbdev = info->par; 346 radeon_bo_kunmap(rbo);
355 rbo = rfb->obj->driver_private; 347 radeon_bo_unpin(rbo);
356 unregister_framebuffer(info); 348 radeon_bo_unreserve(rbo);
357 r = radeon_bo_reserve(rbo, false);
358 if (likely(r == 0)) {
359 radeon_bo_kunmap(rbo);
360 radeon_bo_unpin(rbo);
361 radeon_bo_unreserve(rbo);
362 }
363 drm_fb_helper_free(&rfbdev->helper);
364 framebuffer_release(info);
365 } 349 }
366 350
367 printk(KERN_INFO "unregistered panic notifier\n"); 351 drm_fb_helper_free(&rfbdev->helper);
352 drm_framebuffer_cleanup(&rfb->base);
353 if (rfb->obj)
354 drm_gem_object_unreference_unlocked(rfb->obj);
355
356 framebuffer_release(info);
368 357
369 return 0; 358 return 0;
370} 359}
371EXPORT_SYMBOL(radeonfb_remove);
372MODULE_LICENSE("GPL"); 360MODULE_LICENSE("GPL");
361
362int radeon_fbdev_init(struct radeon_device *rdev)
363{
364 drm_helper_initial_config(rdev->ddev);
365 radeonfb_probe(rdev->ddev);
366 return 0;
367}
368
369void radeon_fbdev_fini(struct radeon_device *rdev)
370{
371 radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
372 rdev->mode_info.rfbdev = NULL;
373}
374
375void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
376{
377 fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
378}
379
380int radeon_fbdev_total_size(struct radeon_device *rdev)
381{
382 struct radeon_bo *robj;
383 int size = 0;
384
385 robj = rdev->mode_info.rfbdev->rfb.obj->driver_private;
386 size += radeon_bo_size(robj);
387 return size;
388}
389
390bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
391{
392 if (robj == rdev->mode_info.rfbdev->rfb.obj->driver_private)
393 return true;
394 return false;
395}
396
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index ef92d147d8f0..28dd3e1b9c3a 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -158,8 +158,7 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
158 args->vram_visible = rdev->mc.real_vram_size; 158 args->vram_visible = rdev->mc.real_vram_size;
159 if (rdev->stollen_vga_memory) 159 if (rdev->stollen_vga_memory)
160 args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); 160 args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
161 if (rdev->fbdev_rbo) 161 args->vram_visible -= radeon_fbdev_total_size(rdev);
162 args->vram_visible -= radeon_bo_size(rdev->fbdev_rbo);
163 args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 - 162 args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 -
164 RADEON_IB_POOL_SIZE*64*1024; 163 RADEON_IB_POOL_SIZE*64*1024;
165 return 0; 164 return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a212041e8b0b..e7afd80a3d69 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -55,6 +55,8 @@ static void radeon_hotplug_work_func(struct work_struct *work)
55 radeon_connector_hotplug(connector); 55 radeon_connector_hotplug(connector);
56 } 56 }
57 /* Just fire off a uevent and let userspace tell us what to do */ 57 /* Just fire off a uevent and let userspace tell us what to do */
58 radeonfb_hotplug(dev);
59
58 drm_sysfs_hotplug_event(dev); 60 drm_sysfs_hotplug_event(dev);
59} 61}
60 62
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 0b8e32776b10..1e9138bf5592 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -39,6 +39,7 @@
39#include <linux/i2c-algo-bit.h> 39#include <linux/i2c-algo-bit.h>
40#include "radeon_fixed.h" 40#include "radeon_fixed.h"
41 41
42struct radeon_bo;
42struct radeon_device; 43struct radeon_device;
43 44
44#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base) 45#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base)
@@ -202,6 +203,8 @@ enum radeon_dvo_chip {
202 DVO_SIL1178, 203 DVO_SIL1178,
203}; 204};
204 205
206struct radeon_kernel_fbdev;
207
205struct radeon_mode_info { 208struct radeon_mode_info {
206 struct atom_context *atom_context; 209 struct atom_context *atom_context;
207 struct card_info *atom_card_info; 210 struct card_info *atom_card_info;
@@ -218,6 +221,9 @@ struct radeon_mode_info {
218 struct drm_property *tmds_pll_property; 221 struct drm_property *tmds_pll_property;
219 /* hardcoded DFP edid from BIOS */ 222 /* hardcoded DFP edid from BIOS */
220 struct edid *bios_hardcoded_edid; 223 struct edid *bios_hardcoded_edid;
224
225 /* pointer to fbdev info structure */
226 struct radeon_kernel_fbdev *rfbdev;
221}; 227};
222 228
223#define MAX_H_CODE_TIMING_LEN 32 229#define MAX_H_CODE_TIMING_LEN 32
@@ -532,11 +538,10 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
532 u16 blue, int regno); 538 u16 blue, int regno);
533extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, 539extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
534 u16 *blue, int regno); 540 u16 *blue, int regno);
535struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, 541void radeon_framebuffer_init(struct drm_device *dev,
536 struct drm_mode_fb_cmd *mode_cmd, 542 struct radeon_framebuffer *rfb,
537 struct drm_gem_object *obj); 543 struct drm_mode_fb_cmd *mode_cmd,
538 544 struct drm_gem_object *obj);
539int radeonfb_probe(struct drm_device *dev);
540 545
541int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); 546int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
542bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev); 547bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev);
@@ -573,4 +578,12 @@ void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
573void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, 578void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
574 struct drm_display_mode *mode, 579 struct drm_display_mode *mode,
575 struct drm_display_mode *adjusted_mode); 580 struct drm_display_mode *adjusted_mode);
581
582/* fbdev layer */
583int radeon_fbdev_init(struct radeon_device *rdev);
584void radeon_fbdev_fini(struct radeon_device *rdev);
585void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
586int radeon_fbdev_total_size(struct radeon_device *rdev);
587bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
588void radeonfb_hotplug(struct drm_device *dev);
576#endif 589#endif