]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/gpu/drm/nouveau/nouveau_state.c
drm/nouveau/device: include the official chipset names
[mirror_ubuntu-artful-kernel.git] / drivers / gpu / drm / nouveau / nouveau_state.c
1 /*
2 * Copyright 2005 Stephane Marchesin
3 * Copyright 2008 Stuart Bennett
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include <linux/swab.h>
27 #include <linux/slab.h>
28 #include "drmP.h"
29 #include "drm.h"
30 #include "drm_sarea.h"
31 #include "drm_crtc_helper.h"
32 #include <linux/vgaarb.h>
33 #include <linux/vga_switcheroo.h>
34
35 #include "nouveau_drv.h"
36 #include <nouveau_drm.h>
37 #include "nouveau_fbcon.h"
38 #include "nouveau_pm.h"
39 #include "nv04_display.h"
40 #include "nv50_display.h"
41 #include "nouveau_acpi.h"
42
43 static void nouveau_stub_takedown(struct drm_device *dev) {}
44 static int nouveau_stub_init(struct drm_device *dev) { return 0; }
45
46 static int nouveau_init_engine_ptrs(struct drm_device *dev)
47 {
48 struct drm_nouveau_private *dev_priv = dev->dev_private;
49 struct nouveau_engine *engine = &dev_priv->engine;
50
51 switch (dev_priv->chipset & 0xf0) {
52 case 0x00:
53 engine->display.early_init = nv04_display_early_init;
54 engine->display.late_takedown = nv04_display_late_takedown;
55 engine->display.create = nv04_display_create;
56 engine->display.destroy = nv04_display_destroy;
57 engine->display.init = nv04_display_init;
58 engine->display.fini = nv04_display_fini;
59 engine->pm.clocks_get = nv04_pm_clocks_get;
60 engine->pm.clocks_pre = nv04_pm_clocks_pre;
61 engine->pm.clocks_set = nv04_pm_clocks_set;
62 break;
63 case 0x10:
64 engine->display.early_init = nv04_display_early_init;
65 engine->display.late_takedown = nv04_display_late_takedown;
66 engine->display.create = nv04_display_create;
67 engine->display.destroy = nv04_display_destroy;
68 engine->display.init = nv04_display_init;
69 engine->display.fini = nv04_display_fini;
70 engine->pm.clocks_get = nv04_pm_clocks_get;
71 engine->pm.clocks_pre = nv04_pm_clocks_pre;
72 engine->pm.clocks_set = nv04_pm_clocks_set;
73 break;
74 case 0x20:
75 engine->display.early_init = nv04_display_early_init;
76 engine->display.late_takedown = nv04_display_late_takedown;
77 engine->display.create = nv04_display_create;
78 engine->display.destroy = nv04_display_destroy;
79 engine->display.init = nv04_display_init;
80 engine->display.fini = nv04_display_fini;
81 engine->pm.clocks_get = nv04_pm_clocks_get;
82 engine->pm.clocks_pre = nv04_pm_clocks_pre;
83 engine->pm.clocks_set = nv04_pm_clocks_set;
84 break;
85 case 0x30:
86 engine->display.early_init = nv04_display_early_init;
87 engine->display.late_takedown = nv04_display_late_takedown;
88 engine->display.create = nv04_display_create;
89 engine->display.destroy = nv04_display_destroy;
90 engine->display.init = nv04_display_init;
91 engine->display.fini = nv04_display_fini;
92 engine->pm.clocks_get = nv04_pm_clocks_get;
93 engine->pm.clocks_pre = nv04_pm_clocks_pre;
94 engine->pm.clocks_set = nv04_pm_clocks_set;
95 engine->pm.voltage_get = nouveau_voltage_gpio_get;
96 engine->pm.voltage_set = nouveau_voltage_gpio_set;
97 break;
98 case 0x40:
99 case 0x60:
100 engine->display.early_init = nv04_display_early_init;
101 engine->display.late_takedown = nv04_display_late_takedown;
102 engine->display.create = nv04_display_create;
103 engine->display.destroy = nv04_display_destroy;
104 engine->display.init = nv04_display_init;
105 engine->display.fini = nv04_display_fini;
106 engine->pm.clocks_get = nv40_pm_clocks_get;
107 engine->pm.clocks_pre = nv40_pm_clocks_pre;
108 engine->pm.clocks_set = nv40_pm_clocks_set;
109 engine->pm.voltage_get = nouveau_voltage_gpio_get;
110 engine->pm.voltage_set = nouveau_voltage_gpio_set;
111 engine->pm.temp_get = nv40_temp_get;
112 engine->pm.pwm_get = nv40_pm_pwm_get;
113 engine->pm.pwm_set = nv40_pm_pwm_set;
114 break;
115 case 0x50:
116 case 0x80: /* gotta love NVIDIA's consistency.. */
117 case 0x90:
118 case 0xa0:
119 engine->display.early_init = nv50_display_early_init;
120 engine->display.late_takedown = nv50_display_late_takedown;
121 engine->display.create = nv50_display_create;
122 engine->display.destroy = nv50_display_destroy;
123 engine->display.init = nv50_display_init;
124 engine->display.fini = nv50_display_fini;
125 switch (dev_priv->chipset) {
126 case 0x84:
127 case 0x86:
128 case 0x92:
129 case 0x94:
130 case 0x96:
131 case 0x98:
132 case 0xa0:
133 case 0xaa:
134 case 0xac:
135 case 0x50:
136 engine->pm.clocks_get = nv50_pm_clocks_get;
137 engine->pm.clocks_pre = nv50_pm_clocks_pre;
138 engine->pm.clocks_set = nv50_pm_clocks_set;
139 break;
140 default:
141 engine->pm.clocks_get = nva3_pm_clocks_get;
142 engine->pm.clocks_pre = nva3_pm_clocks_pre;
143 engine->pm.clocks_set = nva3_pm_clocks_set;
144 break;
145 }
146 engine->pm.voltage_get = nouveau_voltage_gpio_get;
147 engine->pm.voltage_set = nouveau_voltage_gpio_set;
148 if (dev_priv->chipset >= 0x84)
149 engine->pm.temp_get = nv84_temp_get;
150 else
151 engine->pm.temp_get = nv40_temp_get;
152 engine->pm.pwm_get = nv50_pm_pwm_get;
153 engine->pm.pwm_set = nv50_pm_pwm_set;
154 break;
155 case 0xc0:
156 engine->display.early_init = nv50_display_early_init;
157 engine->display.late_takedown = nv50_display_late_takedown;
158 engine->display.create = nv50_display_create;
159 engine->display.destroy = nv50_display_destroy;
160 engine->display.init = nv50_display_init;
161 engine->display.fini = nv50_display_fini;
162 engine->pm.temp_get = nv84_temp_get;
163 engine->pm.clocks_get = nvc0_pm_clocks_get;
164 engine->pm.clocks_pre = nvc0_pm_clocks_pre;
165 engine->pm.clocks_set = nvc0_pm_clocks_set;
166 engine->pm.voltage_get = nouveau_voltage_gpio_get;
167 engine->pm.voltage_set = nouveau_voltage_gpio_set;
168 engine->pm.pwm_get = nv50_pm_pwm_get;
169 engine->pm.pwm_set = nv50_pm_pwm_set;
170 break;
171 case 0xd0:
172 engine->display.early_init = nouveau_stub_init;
173 engine->display.late_takedown = nouveau_stub_takedown;
174 engine->display.create = nvd0_display_create;
175 engine->display.destroy = nvd0_display_destroy;
176 engine->display.init = nvd0_display_init;
177 engine->display.fini = nvd0_display_fini;
178 engine->pm.temp_get = nv84_temp_get;
179 engine->pm.clocks_get = nvc0_pm_clocks_get;
180 engine->pm.clocks_pre = nvc0_pm_clocks_pre;
181 engine->pm.clocks_set = nvc0_pm_clocks_set;
182 engine->pm.voltage_get = nouveau_voltage_gpio_get;
183 engine->pm.voltage_set = nouveau_voltage_gpio_set;
184 break;
185 case 0xe0:
186 engine->display.early_init = nouveau_stub_init;
187 engine->display.late_takedown = nouveau_stub_takedown;
188 engine->display.create = nvd0_display_create;
189 engine->display.destroy = nvd0_display_destroy;
190 engine->display.init = nvd0_display_init;
191 engine->display.fini = nvd0_display_fini;
192 break;
193 default:
194 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
195 return 1;
196 }
197
198 /* headless mode */
199 if (nouveau_modeset == 2) {
200 engine->display.early_init = nouveau_stub_init;
201 engine->display.late_takedown = nouveau_stub_takedown;
202 engine->display.create = nouveau_stub_init;
203 engine->display.init = nouveau_stub_init;
204 engine->display.destroy = nouveau_stub_takedown;
205 }
206
207 return 0;
208 }
209
210 static unsigned int
211 nouveau_vga_set_decode(void *priv, bool state)
212 {
213 struct drm_device *dev = priv;
214 struct drm_nouveau_private *dev_priv = dev->dev_private;
215
216 if (dev_priv->chipset >= 0x40)
217 nv_wr32(dev, 0x88054, state);
218 else
219 nv_wr32(dev, 0x1854, state);
220
221 if (state)
222 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
223 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
224 else
225 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
226 }
227
228 static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
229 enum vga_switcheroo_state state)
230 {
231 struct drm_device *dev = pci_get_drvdata(pdev);
232 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
233 if (state == VGA_SWITCHEROO_ON) {
234 printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
235 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
236 nouveau_pci_resume(pdev);
237 drm_kms_helper_poll_enable(dev);
238 dev->switch_power_state = DRM_SWITCH_POWER_ON;
239 } else {
240 printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
241 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
242 drm_kms_helper_poll_disable(dev);
243 nouveau_switcheroo_optimus_dsm();
244 nouveau_pci_suspend(pdev, pmm);
245 dev->switch_power_state = DRM_SWITCH_POWER_OFF;
246 }
247 }
248
249 static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
250 {
251 struct drm_device *dev = pci_get_drvdata(pdev);
252 nouveau_fbcon_output_poll_changed(dev);
253 }
254
255 static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
256 {
257 struct drm_device *dev = pci_get_drvdata(pdev);
258 bool can_switch;
259
260 spin_lock(&dev->count_lock);
261 can_switch = (dev->open_count == 0);
262 spin_unlock(&dev->count_lock);
263 return can_switch;
264 }
265
266 static const struct vga_switcheroo_client_ops nouveau_switcheroo_ops = {
267 .set_gpu_state = nouveau_switcheroo_set_state,
268 .reprobe = nouveau_switcheroo_reprobe,
269 .can_switch = nouveau_switcheroo_can_switch,
270 };
271
272 int
273 nouveau_card_init(struct drm_device *dev)
274 {
275 struct drm_nouveau_private *dev_priv = dev->dev_private;
276 struct nouveau_engine *engine;
277 int ret;
278
279 vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
280 vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops);
281
282 /* Initialise internal driver API hooks */
283 ret = nouveau_init_engine_ptrs(dev);
284 if (ret)
285 goto out;
286 engine = &dev_priv->engine;
287 spin_lock_init(&dev_priv->context_switch_lock);
288
289 /* Make the CRTCs and I2C buses accessible */
290 ret = engine->display.early_init(dev);
291 if (ret)
292 goto out;
293
294 /* Parse BIOS tables / Run init tables if card not POSTed */
295 ret = nouveau_bios_init(dev);
296 if (ret)
297 goto out_display_early;
298
299 /* workaround an odd issue on nvc1 by disabling the device's
300 * nosnoop capability. hopefully won't cause issues until a
301 * better fix is found - assuming there is one...
302 */
303 if (dev_priv->chipset == 0xc1) {
304 nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
305 }
306
307 ret = nouveau_irq_init(dev);
308 if (ret)
309 goto out_bios;
310
311 ret = nouveau_display_create(dev);
312 if (ret)
313 goto out_irq;
314
315 nouveau_backlight_init(dev);
316 nouveau_pm_init(dev);
317
318 if (dev->mode_config.num_crtc) {
319 ret = nouveau_display_init(dev);
320 if (ret)
321 goto out_pm;
322 }
323
324 return 0;
325
326 out_pm:
327 nouveau_pm_fini(dev);
328 nouveau_backlight_exit(dev);
329 nouveau_display_destroy(dev);
330 out_irq:
331 nouveau_irq_fini(dev);
332 out_bios:
333 nouveau_bios_takedown(dev);
334 out_display_early:
335 engine->display.late_takedown(dev);
336 out:
337 vga_switcheroo_unregister_client(dev->pdev);
338 vga_client_register(dev->pdev, NULL, NULL, NULL);
339 return ret;
340 }
341
342 static void nouveau_card_takedown(struct drm_device *dev)
343 {
344 struct drm_nouveau_private *dev_priv = dev->dev_private;
345 struct nouveau_engine *engine = &dev_priv->engine;
346
347 if (dev->mode_config.num_crtc)
348 nouveau_display_fini(dev);
349
350 nouveau_pm_fini(dev);
351 nouveau_backlight_exit(dev);
352 nouveau_display_destroy(dev);
353
354 nouveau_bios_takedown(dev);
355 engine->display.late_takedown(dev);
356
357 nouveau_irq_fini(dev);
358
359 vga_switcheroo_unregister_client(dev->pdev);
360 vga_client_register(dev->pdev, NULL, NULL, NULL);
361 }
362
363 /* first module load, setup the mmio/fb mapping */
364 /* KMS: we need mmio at load time, not when the first drm client opens. */
365 int nouveau_firstopen(struct drm_device *dev)
366 {
367 return 0;
368 }
369
370 /* if we have an OF card, copy vbios to RAMIN */
371 static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
372 {
373 #if defined(__powerpc__)
374 int size, i;
375 const uint32_t *bios;
376 struct device_node *dn = pci_device_to_OF_node(dev->pdev);
377 if (!dn) {
378 NV_INFO(dev, "Unable to get the OF node\n");
379 return;
380 }
381
382 bios = of_get_property(dn, "NVDA,BMP", &size);
383 if (bios) {
384 for (i = 0; i < size; i += 4)
385 nv_wi32(dev, i, bios[i/4]);
386 NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
387 } else {
388 NV_INFO(dev, "Unable to get the OF bios\n");
389 }
390 #endif
391 }
392
393 int nouveau_load(struct drm_device *dev, unsigned long flags)
394 {
395 struct drm_nouveau_private *dev_priv;
396 uint32_t reg0 = ~0, strap;
397 int ret;
398
399 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
400 if (!dev_priv) {
401 ret = -ENOMEM;
402 goto err_out;
403 }
404 dev_priv->newpriv = dev->dev_private;
405 dev->dev_private = dev_priv;
406 dev_priv->dev = dev;
407
408 NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
409 dev->pci_vendor, dev->pci_device, dev->pdev->class);
410
411 /* determine chipset and derive architecture from it */
412 reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
413 if ((reg0 & 0x0f000000) > 0) {
414 dev_priv->chipset = (reg0 & 0xff00000) >> 20;
415 switch (dev_priv->chipset & 0xf0) {
416 case 0x10:
417 case 0x20:
418 case 0x30:
419 dev_priv->card_type = dev_priv->chipset & 0xf0;
420 break;
421 case 0x40:
422 case 0x60:
423 dev_priv->card_type = NV_40;
424 break;
425 case 0x50:
426 case 0x80:
427 case 0x90:
428 case 0xa0:
429 dev_priv->card_type = NV_50;
430 break;
431 case 0xc0:
432 dev_priv->card_type = NV_C0;
433 break;
434 case 0xd0:
435 dev_priv->card_type = NV_D0;
436 break;
437 case 0xe0:
438 dev_priv->card_type = NV_E0;
439 break;
440 default:
441 break;
442 }
443 } else
444 if ((reg0 & 0xff00fff0) == 0x20004000) {
445 if (reg0 & 0x00f00000)
446 dev_priv->chipset = 0x05;
447 else
448 dev_priv->chipset = 0x04;
449 dev_priv->card_type = NV_04;
450 }
451
452 if (!dev_priv->card_type) {
453 NV_ERROR(dev, "unsupported chipset 0x%08x\n", reg0);
454 ret = -EINVAL;
455 goto err_priv;
456 }
457
458 NV_INFO(dev, "Detected an NV%02x generation card (0x%08x)\n",
459 dev_priv->card_type, reg0);
460
461 /* determine frequency of timing crystal */
462 strap = nv_rd32(dev, 0x101000);
463 if ( dev_priv->chipset < 0x17 ||
464 (dev_priv->chipset >= 0x20 && dev_priv->chipset <= 0x25))
465 strap &= 0x00000040;
466 else
467 strap &= 0x00400040;
468
469 switch (strap) {
470 case 0x00000000: dev_priv->crystal = 13500; break;
471 case 0x00000040: dev_priv->crystal = 14318; break;
472 case 0x00400000: dev_priv->crystal = 27000; break;
473 case 0x00400040: dev_priv->crystal = 25000; break;
474 }
475
476 NV_DEBUG(dev, "crystal freq: %dKHz\n", dev_priv->crystal);
477
478 nouveau_OF_copy_vbios_to_ramin(dev);
479
480 /* For kernel modesetting, init card now and bring up fbcon */
481 ret = nouveau_card_init(dev);
482 if (ret)
483 goto err_priv;
484
485 return 0;
486
487 err_priv:
488 dev->dev_private = dev_priv->newpriv;
489 kfree(dev_priv);
490 err_out:
491 return ret;
492 }
493
494 void nouveau_lastclose(struct drm_device *dev)
495 {
496 vga_switcheroo_process_delayed_switch();
497 }
498
499 int nouveau_unload(struct drm_device *dev)
500 {
501 struct drm_nouveau_private *dev_priv = dev->dev_private;
502
503 nouveau_card_takedown(dev);
504
505 dev->dev_private = dev_priv->newpriv;
506 kfree(dev_priv);
507 return 0;
508 }