aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-03-30 01:34:14 -0400
committerDave Airlie <airlied@redhat.com>2010-04-06 20:24:56 -0400
commit8be48d924c307e72e3797ab5bde81b07a1ccc52d (patch)
tree7d2fec8d40b0a6e9f7bd8a5aef5bb100783ecd44 /drivers/gpu/drm/nouveau
parent386516744ba45d50f42c6999151cc210cb4f96e4 (diff)
drm/kms/fb: move to using fb helper crtc grouping instead of core crtc list
This move to using the list of crtcs in the fb helper and cleans up the whole picking code, now we store the crtc/connectors we want directly into the modeset and we use the modeset directly to set the mode. Fixes from James Simmons and Ben Skeggs. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c121
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.h2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c16
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fbcon.c16
5 files changed, 79 insertions, 78 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 93459e07e829..941339cb8d8b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -627,7 +627,7 @@ struct drm_nouveau_private {
627 struct dentry *channel_root; 627 struct dentry *channel_root;
628 } debugfs; 628 } debugfs;
629 629
630 struct nouveau_fbcon_par *nfbdev; 630 struct nouveau_fbdev *nfbdev;
631}; 631};
632 632
633static inline struct drm_nouveau_private * 633static inline struct drm_nouveau_private *
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 712ee42e3cf8..90843b62d9b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -53,8 +53,8 @@
53static int 53static int
54nouveau_fbcon_sync(struct fb_info *info) 54nouveau_fbcon_sync(struct fb_info *info)
55{ 55{
56 struct nouveau_fbcon_par *par = info->par; 56 struct nouveau_fbdev *nfbdev = info->par;
57 struct drm_device *dev = par->dev; 57 struct drm_device *dev = nfbdev->dev;
58 struct drm_nouveau_private *dev_priv = dev->dev_private; 58 struct drm_nouveau_private *dev_priv = dev->dev_private;
59 struct nouveau_channel *chan = dev_priv->channel; 59 struct nouveau_channel *chan = dev_priv->channel;
60 int ret, i; 60 int ret, i;
@@ -200,9 +200,9 @@ not_fb:
200#endif 200#endif
201 201
202static void 202static void
203nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbcon_par *fbpar) 203nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
204{ 204{
205 struct fb_info *info = fbpar->helper.fbdev; 205 struct fb_info *info = nfbdev->helper.fbdev;
206 struct fb_fillrect rect; 206 struct fb_fillrect rect;
207 207
208 /* Clear the entire fbcon. The drm will program every connector 208 /* Clear the entire fbcon. The drm will program every connector
@@ -218,13 +218,12 @@ nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbcon_par *fbpar)
218} 218}
219 219
220static int 220static int
221nouveau_fbcon_create(struct drm_device *dev, 221nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
222 struct drm_fb_helper_surface_size *sizes, 222 struct drm_fb_helper_surface_size *sizes)
223 struct nouveau_fbcon_par **fbpar_p)
224{ 223{
224 struct drm_device *dev = nfbdev->dev;
225 struct drm_nouveau_private *dev_priv = dev->dev_private; 225 struct drm_nouveau_private *dev_priv = dev->dev_private;
226 struct fb_info *info; 226 struct fb_info *info;
227 struct nouveau_fbcon_par *par;
228 struct drm_framebuffer *fb; 227 struct drm_framebuffer *fb;
229 struct nouveau_framebuffer *nouveau_fb; 228 struct nouveau_framebuffer *nouveau_fb;
230 struct nouveau_bo *nvbo; 229 struct nouveau_bo *nvbo;
@@ -267,27 +266,23 @@ nouveau_fbcon_create(struct drm_device *dev,
267 266
268 mutex_lock(&dev->struct_mutex); 267 mutex_lock(&dev->struct_mutex);
269 268
270 info = framebuffer_alloc(sizeof(struct nouveau_fbcon_par), device); 269 info = framebuffer_alloc(0, device);
271 if (!info) { 270 if (!info) {
272 ret = -ENOMEM; 271 ret = -ENOMEM;
273 goto out_unref; 272 goto out_unref;
274 } 273 }
275 274
276 par = info->par; 275 info->par = nfbdev;
277 nouveau_framebuffer_init(dev, &par->nouveau_fb, &mode_cmd, nvbo);
278 276
279 fb = &par->nouveau_fb.base; 277 nouveau_framebuffer_init(dev, &nfbdev->nouveau_fb, &mode_cmd, nvbo);
280 /* setup helper */
281 par->helper.fb = fb;
282 par->helper.fbdev = info;
283 par->helper.funcs = &nouveau_fbcon_helper_funcs;
284 par->helper.dev = dev;
285 278
286 *fbpar_p = par; 279 nouveau_fb = &nfbdev->nouveau_fb;
280 fb = &nouveau_fb->base;
287 281
288 ret = drm_fb_helper_init_crtc_count(&par->helper, 2, 4); 282 /* setup helper */
289 if (ret) 283 nfbdev->helper.fb = fb;
290 goto out_unref; 284 nfbdev->helper.fbdev = info;
285 nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
291 286
292 strcpy(info->fix.id, "nouveaufb"); 287 strcpy(info->fix.id, "nouveaufb");
293 if (nouveau_nofbaccel) 288 if (nouveau_nofbaccel)
@@ -305,7 +300,7 @@ nouveau_fbcon_create(struct drm_device *dev,
305 info->screen_size = size; 300 info->screen_size = size;
306 301
307 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); 302 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
308 drm_fb_helper_fill_var(info, &par->helper, sizes->fb_width, sizes->fb_height); 303 drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height);
309 304
310 /* FIXME: we really shouldn't expose mmio space at all */ 305 /* FIXME: we really shouldn't expose mmio space at all */
311 info->fix.mmio_start = pci_resource_start(dev->pdev, 1); 306 info->fix.mmio_start = pci_resource_start(dev->pdev, 1);
@@ -338,8 +333,6 @@ nouveau_fbcon_create(struct drm_device *dev,
338 info->pixmap.flags = FB_PIXMAP_SYSTEM; 333 info->pixmap.flags = FB_PIXMAP_SYSTEM;
339 info->pixmap.scan_align = 1; 334 info->pixmap.scan_align = 1;
340 335
341 par->dev = dev;
342
343 if (dev_priv->channel && !nouveau_nofbaccel) { 336 if (dev_priv->channel && !nouveau_nofbaccel) {
344 switch (dev_priv->card_type) { 337 switch (dev_priv->card_type) {
345 case NV_50: 338 case NV_50:
@@ -353,7 +346,7 @@ nouveau_fbcon_create(struct drm_device *dev,
353 }; 346 };
354 } 347 }
355 348
356 nouveau_fbcon_zfill(dev, par); 349 nouveau_fbcon_zfill(dev, nfbdev);
357 350
358 /* To allow resizeing without swapping buffers */ 351 /* To allow resizeing without swapping buffers */
359 NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n", 352 NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
@@ -372,66 +365,56 @@ out:
372} 365}
373 366
374static int 367static int
375nouveau_fbcon_find_or_create_single(struct drm_device *dev, 368nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
376 struct drm_fb_helper_surface_size *sizes, 369 struct drm_fb_helper_surface_size *sizes)
377 struct drm_fb_helper **fb_ptr)
378{ 370{
379 struct drm_nouveau_private *dev_priv = dev->dev_private; 371 struct nouveau_fbdev *nfbdev = (struct nouveau_fbdev *)helper;
380 struct nouveau_fbcon_par *fbpar;
381 int new_fb = 0; 372 int new_fb = 0;
382 int ret; 373 int ret;
383 374
384 if (!dev_priv->nfbdev) { 375 if (!helper->fb) {
385 ret = nouveau_fbcon_create(dev, sizes, 376 ret = nouveau_fbcon_create(nfbdev, sizes);
386 &fbpar);
387 if (ret) 377 if (ret)
388 return ret; 378 return ret;
389 dev_priv->nfbdev = fbpar;
390 new_fb = 1; 379 new_fb = 1;
391 } else {
392 fbpar = dev_priv->nfbdev;
393 if (fbpar->nouveau_fb.base.width < sizes->surface_width ||
394 fbpar->nouveau_fb.base.height < sizes->surface_height) {
395 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
396 return -EINVAL;
397 }
398 } 380 }
399 *fb_ptr = &fbpar->helper;
400 return new_fb; 381 return new_fb;
401} 382}
402 383
403static int 384static int
404nouveau_fbcon_probe(struct drm_device *dev) 385nouveau_fbcon_probe(struct nouveau_fbdev *nfbdev)
405{ 386{
406 NV_DEBUG_KMS(dev, "\n"); 387 NV_DEBUG_KMS(nfbdev->dev, "\n");
407 388
408 return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_find_or_create_single); 389 return drm_fb_helper_single_fb_probe(&nfbdev->helper, 32);
409} 390}
410 391
411int 392int
412nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbcon_par *fbpar) 393nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
413{ 394{
414 struct nouveau_framebuffer *nouveau_fb = &fbpar->nouveau_fb; 395 struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
415 struct fb_info *info; 396 struct fb_info *info;
416 397
417 info = fbpar->helper.fbdev; 398 if (nfbdev->helper.fbdev) {
418 399 info = nfbdev->helper.fbdev;
419 unregister_framebuffer(info); 400 unregister_framebuffer(info);
420 nouveau_bo_unmap(nouveau_fb->nvbo); 401 framebuffer_release(info);
421 drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); 402 }
422 nouveau_fb->nvbo = NULL;
423 drm_fb_helper_free(&fbpar->helper);
424 403
404 if (nouveau_fb->nvbo) {
405 nouveau_bo_unmap(nouveau_fb->nvbo);
406 drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
407 nouveau_fb->nvbo = NULL;
408 }
409 drm_fb_helper_free(&nfbdev->helper);
425 drm_framebuffer_cleanup(&nouveau_fb->base); 410 drm_framebuffer_cleanup(&nouveau_fb->base);
426 framebuffer_release(info);
427
428 return 0; 411 return 0;
429} 412}
430 413
431void nouveau_fbcon_gpu_lockup(struct fb_info *info) 414void nouveau_fbcon_gpu_lockup(struct fb_info *info)
432{ 415{
433 struct nouveau_fbcon_par *par = info->par; 416 struct nouveau_fbdev *nfbdev = info->par;
434 struct drm_device *dev = par->dev; 417 struct drm_device *dev = nfbdev->dev;
435 418
436 NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); 419 NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
437 info->flags |= FBINFO_HWACCEL_DISABLED; 420 info->flags |= FBINFO_HWACCEL_DISABLED;
@@ -439,15 +422,33 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info)
439 422
440int nouveau_fbcon_init(struct drm_device *dev) 423int nouveau_fbcon_init(struct drm_device *dev)
441{ 424{
442 drm_helper_initial_config(dev); 425 struct drm_nouveau_private *dev_priv = dev->dev_private;
443 nouveau_fbcon_probe(dev); 426 struct nouveau_fbdev *nfbdev;
427
428 nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
429 if (!nfbdev)
430 return -ENOMEM;
431
432 nfbdev->dev = dev;
433 dev_priv->nfbdev = nfbdev;
434
435 drm_fb_helper_init_crtc_count(dev, &nfbdev->helper,
436 2, 4);
437 nfbdev->helper.fb_probe = nouveau_fbcon_find_or_create_single;
438 drm_fb_helper_initial_config(&nfbdev->helper);
439 nouveau_fbcon_probe(nfbdev);
444 return 0; 440 return 0;
445} 441}
446 442
447void nouveau_fbcon_fini(struct drm_device *dev) 443void nouveau_fbcon_fini(struct drm_device *dev)
448{ 444{
449 struct drm_nouveau_private *dev_priv = dev->dev_private; 445 struct drm_nouveau_private *dev_priv = dev->dev_private;
446
447 if (!dev_priv->nfbdev)
448 return;
449
450 nouveau_fbcon_destroy(dev, dev_priv->nfbdev); 450 nouveau_fbcon_destroy(dev, dev_priv->nfbdev);
451 kfree(dev_priv->nfbdev);
451 dev_priv->nfbdev = NULL; 452 dev_priv->nfbdev = NULL;
452} 453}
453 454
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
index fa66cb9fa4d4..7835b5685555 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -30,7 +30,7 @@
30#include "drm_fb_helper.h" 30#include "drm_fb_helper.h"
31 31
32#include "nouveau_fb.h" 32#include "nouveau_fb.h"
33struct nouveau_fbcon_par { 33struct nouveau_fbdev {
34 struct drm_fb_helper helper; 34 struct drm_fb_helper helper;
35 struct nouveau_framebuffer nouveau_fb; 35 struct nouveau_framebuffer nouveau_fb;
36 struct list_head fbdev_list; 36 struct list_head fbdev_list;
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 813b25cec726..603090ee6ac7 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -30,8 +30,8 @@
30void 30void
31nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) 31nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
32{ 32{
33 struct nouveau_fbcon_par *par = info->par; 33 struct nouveau_fbdev *nfbdev = info->par;
34 struct drm_device *dev = par->dev; 34 struct drm_device *dev = nfbdev->dev;
35 struct drm_nouveau_private *dev_priv = dev->dev_private; 35 struct drm_nouveau_private *dev_priv = dev->dev_private;
36 struct nouveau_channel *chan = dev_priv->channel; 36 struct nouveau_channel *chan = dev_priv->channel;
37 37
@@ -57,8 +57,8 @@ nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
57void 57void
58nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 58nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
59{ 59{
60 struct nouveau_fbcon_par *par = info->par; 60 struct nouveau_fbdev *nfbdev = info->par;
61 struct drm_device *dev = par->dev; 61 struct drm_device *dev = nfbdev->dev;
62 struct drm_nouveau_private *dev_priv = dev->dev_private; 62 struct drm_nouveau_private *dev_priv = dev->dev_private;
63 struct nouveau_channel *chan = dev_priv->channel; 63 struct nouveau_channel *chan = dev_priv->channel;
64 64
@@ -91,8 +91,8 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
91void 91void
92nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 92nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
93{ 93{
94 struct nouveau_fbcon_par *par = info->par; 94 struct nouveau_fbdev *nfbdev = info->par;
95 struct drm_device *dev = par->dev; 95 struct drm_device *dev = nfbdev->dev;
96 struct drm_nouveau_private *dev_priv = dev->dev_private; 96 struct drm_nouveau_private *dev_priv = dev->dev_private;
97 struct nouveau_channel *chan = dev_priv->channel; 97 struct nouveau_channel *chan = dev_priv->channel;
98 uint32_t fg; 98 uint32_t fg;
@@ -179,8 +179,8 @@ nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle)
179int 179int
180nv04_fbcon_accel_init(struct fb_info *info) 180nv04_fbcon_accel_init(struct fb_info *info)
181{ 181{
182 struct nouveau_fbcon_par *par = info->par; 182 struct nouveau_fbdev *nfbdev = info->par;
183 struct drm_device *dev = par->dev; 183 struct drm_device *dev = nfbdev->dev;
184 struct drm_nouveau_private *dev_priv = dev->dev_private; 184 struct drm_nouveau_private *dev_priv = dev->dev_private;
185 struct nouveau_channel *chan = dev_priv->channel; 185 struct nouveau_channel *chan = dev_priv->channel;
186 const int sub = NvSubCtxSurf2D; 186 const int sub = NvSubCtxSurf2D;
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
index 25a3cd8794f9..f2410489cd35 100644
--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
@@ -6,8 +6,8 @@
6void 6void
7nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 7nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
8{ 8{
9 struct nouveau_fbcon_par *par = info->par; 9 struct nouveau_fbdev *nfbdev = info->par;
10 struct drm_device *dev = par->dev; 10 struct drm_device *dev = nfbdev->dev;
11 struct drm_nouveau_private *dev_priv = dev->dev_private; 11 struct drm_nouveau_private *dev_priv = dev->dev_private;
12 struct nouveau_channel *chan = dev_priv->channel; 12 struct nouveau_channel *chan = dev_priv->channel;
13 13
@@ -49,8 +49,8 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
49void 49void
50nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) 50nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
51{ 51{
52 struct nouveau_fbcon_par *par = info->par; 52 struct nouveau_fbdev *nfbdev = info->par;
53 struct drm_device *dev = par->dev; 53 struct drm_device *dev = nfbdev->dev;
54 struct drm_nouveau_private *dev_priv = dev->dev_private; 54 struct drm_nouveau_private *dev_priv = dev->dev_private;
55 struct nouveau_channel *chan = dev_priv->channel; 55 struct nouveau_channel *chan = dev_priv->channel;
56 56
@@ -84,8 +84,8 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
84void 84void
85nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 85nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
86{ 86{
87 struct nouveau_fbcon_par *par = info->par; 87 struct nouveau_fbdev *nfbdev = info->par;
88 struct drm_device *dev = par->dev; 88 struct drm_device *dev = nfbdev->dev;
89 struct drm_nouveau_private *dev_priv = dev->dev_private; 89 struct drm_nouveau_private *dev_priv = dev->dev_private;
90 struct nouveau_channel *chan = dev_priv->channel; 90 struct nouveau_channel *chan = dev_priv->channel;
91 uint32_t width, dwords, *data = (uint32_t *)image->data; 91 uint32_t width, dwords, *data = (uint32_t *)image->data;
@@ -152,8 +152,8 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
152int 152int
153nv50_fbcon_accel_init(struct fb_info *info) 153nv50_fbcon_accel_init(struct fb_info *info)
154{ 154{
155 struct nouveau_fbcon_par *par = info->par; 155 struct nouveau_fbdev *nfbdev = info->par;
156 struct drm_device *dev = par->dev; 156 struct drm_device *dev = nfbdev->dev;
157 struct drm_nouveau_private *dev_priv = dev->dev_private; 157 struct drm_nouveau_private *dev_priv = dev->dev_private;
158 struct nouveau_channel *chan = dev_priv->channel; 158 struct nouveau_channel *chan = dev_priv->channel;
159 struct nouveau_gpuobj *eng2d = NULL; 159 struct nouveau_gpuobj *eng2d = NULL;