aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c56
-rw-r--r--drivers/gpu/drm/nouveau/nv04_display.c46
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c16
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h6
6 files changed, 106 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index eeaf1f15a42..1de5eb53e01 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -263,6 +263,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
263 if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) 263 if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
264 nouveau_mem_reset_agp(dev); 264 nouveau_mem_reset_agp(dev);
265 265
266 /* Make the CRTCs accessible */
267 engine->display.early_init(dev);
268
266 NV_INFO(dev, "POSTing device...\n"); 269 NV_INFO(dev, "POSTing device...\n");
267 ret = nouveau_run_vbios_init(dev); 270 ret = nouveau_run_vbios_init(dev);
268 if (ret) 271 if (ret)
@@ -325,10 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
325 NV_ERROR(dev, "Could not pin/map cursor.\n"); 328 NV_ERROR(dev, "Could not pin/map cursor.\n");
326 } 329 }
327 330
328 if (dev_priv->card_type < NV_50) 331 engine->display.init(dev);
329 nv04_display_restore(dev);
330 else
331 nv50_display_init(dev);
332 332
333 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 333 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
334 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 334 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 8590032d36a..0687e6ab918 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -351,6 +351,14 @@ struct nouveau_pgraph_engine {
351 uint32_t size, uint32_t pitch); 351 uint32_t size, uint32_t pitch);
352}; 352};
353 353
354struct nouveau_display_engine {
355 int (*early_init)(struct drm_device *);
356 void (*late_takedown)(struct drm_device *);
357 int (*create)(struct drm_device *);
358 int (*init)(struct drm_device *);
359 void (*destroy)(struct drm_device *);
360};
361
354struct nouveau_engine { 362struct nouveau_engine {
355 struct nouveau_instmem_engine instmem; 363 struct nouveau_instmem_engine instmem;
356 struct nouveau_mc_engine mc; 364 struct nouveau_mc_engine mc;
@@ -358,6 +366,7 @@ struct nouveau_engine {
358 struct nouveau_fb_engine fb; 366 struct nouveau_fb_engine fb;
359 struct nouveau_pgraph_engine graph; 367 struct nouveau_pgraph_engine graph;
360 struct nouveau_fifo_engine fifo; 368 struct nouveau_fifo_engine fifo;
369 struct nouveau_display_engine display;
361}; 370};
362 371
363struct nouveau_pll_vals { 372struct nouveau_pll_vals {
@@ -1081,9 +1090,11 @@ extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
1081extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); 1090extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
1082 1091
1083/* nv04_display.c */ 1092/* nv04_display.c */
1093extern int nv04_display_early_init(struct drm_device *);
1094extern void nv04_display_late_takedown(struct drm_device *);
1084extern int nv04_display_create(struct drm_device *); 1095extern int nv04_display_create(struct drm_device *);
1096extern int nv04_display_init(struct drm_device *);
1085extern void nv04_display_destroy(struct drm_device *); 1097extern void nv04_display_destroy(struct drm_device *);
1086extern void nv04_display_restore(struct drm_device *);
1087 1098
1088/* nv04_crtc.c */ 1099/* nv04_crtc.c */
1089extern int nv04_crtc_create(struct drm_device *, int index); 1100extern int nv04_crtc_create(struct drm_device *, int index);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 8d59c904b04..17176ad5b22 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -84,6 +84,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
84 engine->fifo.destroy_context = nv04_fifo_destroy_context; 84 engine->fifo.destroy_context = nv04_fifo_destroy_context;
85 engine->fifo.load_context = nv04_fifo_load_context; 85 engine->fifo.load_context = nv04_fifo_load_context;
86 engine->fifo.unload_context = nv04_fifo_unload_context; 86 engine->fifo.unload_context = nv04_fifo_unload_context;
87 engine->display.early_init = nv04_display_early_init;
88 engine->display.late_takedown = nv04_display_late_takedown;
89 engine->display.create = nv04_display_create;
90 engine->display.init = nv04_display_init;
91 engine->display.destroy = nv04_display_destroy;
87 break; 92 break;
88 case 0x10: 93 case 0x10:
89 engine->instmem.init = nv04_instmem_init; 94 engine->instmem.init = nv04_instmem_init;
@@ -126,6 +131,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
126 engine->fifo.destroy_context = nv10_fifo_destroy_context; 131 engine->fifo.destroy_context = nv10_fifo_destroy_context;
127 engine->fifo.load_context = nv10_fifo_load_context; 132 engine->fifo.load_context = nv10_fifo_load_context;
128 engine->fifo.unload_context = nv10_fifo_unload_context; 133 engine->fifo.unload_context = nv10_fifo_unload_context;
134 engine->display.early_init = nv04_display_early_init;
135 engine->display.late_takedown = nv04_display_late_takedown;
136 engine->display.create = nv04_display_create;
137 engine->display.init = nv04_display_init;
138 engine->display.destroy = nv04_display_destroy;
129 break; 139 break;
130 case 0x20: 140 case 0x20:
131 engine->instmem.init = nv04_instmem_init; 141 engine->instmem.init = nv04_instmem_init;
@@ -168,6 +178,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
168 engine->fifo.destroy_context = nv10_fifo_destroy_context; 178 engine->fifo.destroy_context = nv10_fifo_destroy_context;
169 engine->fifo.load_context = nv10_fifo_load_context; 179 engine->fifo.load_context = nv10_fifo_load_context;
170 engine->fifo.unload_context = nv10_fifo_unload_context; 180 engine->fifo.unload_context = nv10_fifo_unload_context;
181 engine->display.early_init = nv04_display_early_init;
182 engine->display.late_takedown = nv04_display_late_takedown;
183 engine->display.create = nv04_display_create;
184 engine->display.init = nv04_display_init;
185 engine->display.destroy = nv04_display_destroy;
171 break; 186 break;
172 case 0x30: 187 case 0x30:
173 engine->instmem.init = nv04_instmem_init; 188 engine->instmem.init = nv04_instmem_init;
@@ -210,6 +225,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
210 engine->fifo.destroy_context = nv10_fifo_destroy_context; 225 engine->fifo.destroy_context = nv10_fifo_destroy_context;
211 engine->fifo.load_context = nv10_fifo_load_context; 226 engine->fifo.load_context = nv10_fifo_load_context;
212 engine->fifo.unload_context = nv10_fifo_unload_context; 227 engine->fifo.unload_context = nv10_fifo_unload_context;
228 engine->display.early_init = nv04_display_early_init;
229 engine->display.late_takedown = nv04_display_late_takedown;
230 engine->display.create = nv04_display_create;
231 engine->display.init = nv04_display_init;
232 engine->display.destroy = nv04_display_destroy;
213 break; 233 break;
214 case 0x40: 234 case 0x40:
215 case 0x60: 235 case 0x60:
@@ -253,6 +273,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
253 engine->fifo.destroy_context = nv40_fifo_destroy_context; 273 engine->fifo.destroy_context = nv40_fifo_destroy_context;
254 engine->fifo.load_context = nv40_fifo_load_context; 274 engine->fifo.load_context = nv40_fifo_load_context;
255 engine->fifo.unload_context = nv40_fifo_unload_context; 275 engine->fifo.unload_context = nv40_fifo_unload_context;
276 engine->display.early_init = nv04_display_early_init;
277 engine->display.late_takedown = nv04_display_late_takedown;
278 engine->display.create = nv04_display_create;
279 engine->display.init = nv04_display_init;
280 engine->display.destroy = nv04_display_destroy;
256 break; 281 break;
257 case 0x50: 282 case 0x50:
258 case 0x80: /* gotta love NVIDIA's consistency.. */ 283 case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -297,6 +322,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
297 engine->fifo.destroy_context = nv50_fifo_destroy_context; 322 engine->fifo.destroy_context = nv50_fifo_destroy_context;
298 engine->fifo.load_context = nv50_fifo_load_context; 323 engine->fifo.load_context = nv50_fifo_load_context;
299 engine->fifo.unload_context = nv50_fifo_unload_context; 324 engine->fifo.unload_context = nv50_fifo_unload_context;
325 engine->display.early_init = nv50_display_early_init;
326 engine->display.late_takedown = nv50_display_late_takedown;
327 engine->display.create = nv50_display_create;
328 engine->display.init = nv50_display_init;
329 engine->display.destroy = nv50_display_destroy;
300 break; 330 break;
301 default: 331 default:
302 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 332 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -415,10 +445,15 @@ nouveau_card_init(struct drm_device *dev)
415 engine = &dev_priv->engine; 445 engine = &dev_priv->engine;
416 spin_lock_init(&dev_priv->context_switch_lock); 446 spin_lock_init(&dev_priv->context_switch_lock);
417 447
448 /* Make the CRTCs and I2C buses accessible */
449 ret = engine->display.early_init(dev);
450 if (ret)
451 goto out;
452
418 /* Parse BIOS tables / Run init tables if card not POSTed */ 453 /* Parse BIOS tables / Run init tables if card not POSTed */
419 ret = nouveau_bios_init(dev); 454 ret = nouveau_bios_init(dev);
420 if (ret) 455 if (ret)
421 goto out; 456 goto out_display_early;
422 457
423 ret = nouveau_mem_detect(dev); 458 ret = nouveau_mem_detect(dev);
424 if (ret) 459 if (ret)
@@ -474,10 +509,7 @@ nouveau_card_init(struct drm_device *dev)
474 goto out_graph; 509 goto out_graph;
475 } 510 }
476 511
477 if (dev_priv->card_type >= NV_50) 512 ret = engine->display.create(dev);
478 ret = nv50_display_create(dev);
479 else
480 ret = nv04_display_create(dev);
481 if (ret) 513 if (ret)
482 goto out_fifo; 514 goto out_fifo;
483 515
@@ -511,10 +543,7 @@ nouveau_card_init(struct drm_device *dev)
511out_irq: 543out_irq:
512 drm_irq_uninstall(dev); 544 drm_irq_uninstall(dev);
513out_display: 545out_display:
514 if (dev_priv->card_type >= NV_50) 546 engine->display.destroy(dev);
515 nv50_display_destroy(dev);
516 else
517 nv04_display_destroy(dev);
518out_fifo: 547out_fifo:
519 if (!nouveau_noaccel) 548 if (!nouveau_noaccel)
520 engine->fifo.takedown(dev); 549 engine->fifo.takedown(dev);
@@ -538,6 +567,8 @@ out_gpuobj_early:
538 nouveau_gpuobj_late_takedown(dev); 567 nouveau_gpuobj_late_takedown(dev);
539out_bios: 568out_bios:
540 nouveau_bios_takedown(dev); 569 nouveau_bios_takedown(dev);
570out_display_early:
571 engine->display.late_takedown(dev);
541out: 572out:
542 vga_client_register(dev->pdev, NULL, NULL, NULL); 573 vga_client_register(dev->pdev, NULL, NULL, NULL);
543 return ret; 574 return ret;
@@ -562,6 +593,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
562 engine->fb.takedown(dev); 593 engine->fb.takedown(dev);
563 engine->timer.takedown(dev); 594 engine->timer.takedown(dev);
564 engine->mc.takedown(dev); 595 engine->mc.takedown(dev);
596 engine->display.late_takedown(dev);
565 597
566 mutex_lock(&dev->struct_mutex); 598 mutex_lock(&dev->struct_mutex);
567 ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); 599 ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
@@ -798,13 +830,11 @@ void nouveau_lastclose(struct drm_device *dev)
798int nouveau_unload(struct drm_device *dev) 830int nouveau_unload(struct drm_device *dev)
799{ 831{
800 struct drm_nouveau_private *dev_priv = dev->dev_private; 832 struct drm_nouveau_private *dev_priv = dev->dev_private;
833 struct nouveau_engine *engine = &dev_priv->engine;
801 834
802 drm_kms_helper_poll_fini(dev); 835 drm_kms_helper_poll_fini(dev);
803 nouveau_fbcon_fini(dev); 836 nouveau_fbcon_fini(dev);
804 if (dev_priv->card_type >= NV_50) 837 engine->display.destroy(dev);
805 nv50_display_destroy(dev);
806 else
807 nv04_display_destroy(dev);
808 nouveau_card_takedown(dev); 838 nouveau_card_takedown(dev);
809 839
810 iounmap(dev_priv->mmio); 840 iounmap(dev_priv->mmio);
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
index c6df391ebb2..cd70bd82761 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -76,6 +76,32 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
76} 76}
77 77
78int 78int
79nv04_display_early_init(struct drm_device *dev)
80{
81 /* Unlock the VGA CRTCs. */
82 NVLockVgaCrtcs(dev, false);
83
84 /* Make sure the CRTCs aren't in slaved mode. */
85 if (nv_two_heads(dev)) {
86 nv04_display_store_initial_head_owner(dev);
87 NVSetOwner(dev, 0);
88 }
89
90 return 0;
91}
92
93void
94nv04_display_late_takedown(struct drm_device *dev)
95{
96 struct drm_nouveau_private *dev_priv = dev->dev_private;
97
98 if (nv_two_heads(dev))
99 NVSetOwner(dev, dev_priv->crtc_owner);
100
101 NVLockVgaCrtcs(dev, true);
102}
103
104int
79nv04_display_create(struct drm_device *dev) 105nv04_display_create(struct drm_device *dev)
80{ 106{
81 struct drm_nouveau_private *dev_priv = dev->dev_private; 107 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -87,13 +113,6 @@ nv04_display_create(struct drm_device *dev)
87 113
88 NV_DEBUG_KMS(dev, "\n"); 114 NV_DEBUG_KMS(dev, "\n");
89 115
90 NVLockVgaCrtcs(dev, false);
91
92 if (nv_two_heads(dev)) {
93 nv04_display_store_initial_head_owner(dev);
94 NVSetOwner(dev, 0);
95 }
96
97 nouveau_hw_save_vga_fonts(dev, 1); 116 nouveau_hw_save_vga_fonts(dev, 1);
98 117
99 drm_mode_config_init(dev); 118 drm_mode_config_init(dev);
@@ -176,7 +195,6 @@ nv04_display_create(struct drm_device *dev)
176void 195void
177nv04_display_destroy(struct drm_device *dev) 196nv04_display_destroy(struct drm_device *dev)
178{ 197{
179 struct drm_nouveau_private *dev_priv = dev->dev_private;
180 struct drm_encoder *encoder; 198 struct drm_encoder *encoder;
181 struct drm_crtc *crtc; 199 struct drm_crtc *crtc;
182 200
@@ -204,20 +222,14 @@ nv04_display_destroy(struct drm_device *dev)
204 drm_mode_config_cleanup(dev); 222 drm_mode_config_cleanup(dev);
205 223
206 nouveau_hw_save_vga_fonts(dev, 0); 224 nouveau_hw_save_vga_fonts(dev, 0);
207
208 if (nv_two_heads(dev))
209 NVSetOwner(dev, dev_priv->crtc_owner);
210 NVLockVgaCrtcs(dev, true);
211} 225}
212 226
213void 227int
214nv04_display_restore(struct drm_device *dev) 228nv04_display_init(struct drm_device *dev)
215{ 229{
216 struct drm_encoder *encoder; 230 struct drm_encoder *encoder;
217 struct drm_crtc *crtc; 231 struct drm_crtc *crtc;
218 232
219 NVLockVgaCrtcs(dev, false);
220
221 /* meh.. modeset apparently doesn't setup all the regs and depends 233 /* meh.. modeset apparently doesn't setup all the regs and depends
222 * on pre-existing state, for now load the state of the card *before* 234 * on pre-existing state, for now load the state of the card *before*
223 * nouveau was loaded, and then do a modeset. 235 * nouveau was loaded, and then do a modeset.
@@ -234,5 +246,7 @@ nv04_display_restore(struct drm_device *dev)
234 246
235 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 247 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
236 crtc->funcs->restore(crtc); 248 crtc->funcs->restore(crtc);
249
250 return 0;
237} 251}
238 252
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index fbd91c251ee..13a44898563 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -178,6 +178,17 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
178} 178}
179 179
180int 180int
181nv50_display_early_init(struct drm_device *dev)
182{
183 return 0;
184}
185
186void
187nv50_display_late_takedown(struct drm_device *dev)
188{
189}
190
191int
181nv50_display_init(struct drm_device *dev) 192nv50_display_init(struct drm_device *dev)
182{ 193{
183 struct drm_nouveau_private *dev_priv = dev->dev_private; 194 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -528,7 +539,8 @@ int nv50_display_create(struct drm_device *dev)
528 return 0; 539 return 0;
529} 540}
530 541
531int nv50_display_destroy(struct drm_device *dev) 542void
543nv50_display_destroy(struct drm_device *dev)
532{ 544{
533 struct drm_nouveau_private *dev_priv = dev->dev_private; 545 struct drm_nouveau_private *dev_priv = dev->dev_private;
534 546
@@ -538,8 +550,6 @@ int nv50_display_destroy(struct drm_device *dev)
538 550
539 nv50_display_disable(dev); 551 nv50_display_disable(dev);
540 nv50_evo_channel_del(&dev_priv->evo); 552 nv50_evo_channel_del(&dev_priv->evo);
541
542 return 0;
543} 553}
544 554
545static u16 555static u16
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index 581d405ac01..c551f0b85ee 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -38,9 +38,11 @@
38void nv50_display_irq_handler(struct drm_device *dev); 38void nv50_display_irq_handler(struct drm_device *dev);
39void nv50_display_irq_handler_bh(struct work_struct *work); 39void nv50_display_irq_handler_bh(struct work_struct *work);
40void nv50_display_irq_hotplug_bh(struct work_struct *work); 40void nv50_display_irq_hotplug_bh(struct work_struct *work);
41int nv50_display_init(struct drm_device *dev); 41int nv50_display_early_init(struct drm_device *dev);
42void nv50_display_late_takedown(struct drm_device *dev);
42int nv50_display_create(struct drm_device *dev); 43int nv50_display_create(struct drm_device *dev);
43int nv50_display_destroy(struct drm_device *dev); 44int nv50_display_init(struct drm_device *dev);
45void nv50_display_destroy(struct drm_device *dev);
44int nv50_crtc_blank(struct nouveau_crtc *, bool blank); 46int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
45int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); 47int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
46 48