2 * Copyright 2005 Stephane Marchesin
3 * Copyright 2008 Stuart Bennett
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:
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
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.
26 #include <linux/swab.h>
27 #include <linux/slab.h>
30 #include "drm_sarea.h"
31 #include "drm_crtc_helper.h"
32 #include <linux/vgaarb.h>
33 #include <linux/vga_switcheroo.h>
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"
42 static void nouveau_stub_takedown(struct drm_device
*dev
) {}
43 static int nouveau_stub_init(struct drm_device
*dev
) { return 0; }
45 static int nouveau_init_engine_ptrs(struct drm_device
*dev
)
47 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
48 struct nouveau_engine
*engine
= &dev_priv
->engine
;
50 switch (dev_priv
->chipset
& 0xf0) {
52 engine
->display
.early_init
= nv04_display_early_init
;
53 engine
->display
.late_takedown
= nv04_display_late_takedown
;
54 engine
->display
.create
= nv04_display_create
;
55 engine
->display
.destroy
= nv04_display_destroy
;
56 engine
->display
.init
= nv04_display_init
;
57 engine
->display
.fini
= nv04_display_fini
;
58 engine
->pm
.clocks_get
= nv04_pm_clocks_get
;
59 engine
->pm
.clocks_pre
= nv04_pm_clocks_pre
;
60 engine
->pm
.clocks_set
= nv04_pm_clocks_set
;
63 engine
->display
.early_init
= nv04_display_early_init
;
64 engine
->display
.late_takedown
= nv04_display_late_takedown
;
65 engine
->display
.create
= nv04_display_create
;
66 engine
->display
.destroy
= nv04_display_destroy
;
67 engine
->display
.init
= nv04_display_init
;
68 engine
->display
.fini
= nv04_display_fini
;
69 engine
->pm
.clocks_get
= nv04_pm_clocks_get
;
70 engine
->pm
.clocks_pre
= nv04_pm_clocks_pre
;
71 engine
->pm
.clocks_set
= nv04_pm_clocks_set
;
74 engine
->display
.early_init
= nv04_display_early_init
;
75 engine
->display
.late_takedown
= nv04_display_late_takedown
;
76 engine
->display
.create
= nv04_display_create
;
77 engine
->display
.destroy
= nv04_display_destroy
;
78 engine
->display
.init
= nv04_display_init
;
79 engine
->display
.fini
= nv04_display_fini
;
80 engine
->pm
.clocks_get
= nv04_pm_clocks_get
;
81 engine
->pm
.clocks_pre
= nv04_pm_clocks_pre
;
82 engine
->pm
.clocks_set
= nv04_pm_clocks_set
;
85 engine
->display
.early_init
= nv04_display_early_init
;
86 engine
->display
.late_takedown
= nv04_display_late_takedown
;
87 engine
->display
.create
= nv04_display_create
;
88 engine
->display
.destroy
= nv04_display_destroy
;
89 engine
->display
.init
= nv04_display_init
;
90 engine
->display
.fini
= nv04_display_fini
;
91 engine
->pm
.clocks_get
= nv04_pm_clocks_get
;
92 engine
->pm
.clocks_pre
= nv04_pm_clocks_pre
;
93 engine
->pm
.clocks_set
= nv04_pm_clocks_set
;
94 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
95 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
99 engine
->display
.early_init
= nv04_display_early_init
;
100 engine
->display
.late_takedown
= nv04_display_late_takedown
;
101 engine
->display
.create
= nv04_display_create
;
102 engine
->display
.destroy
= nv04_display_destroy
;
103 engine
->display
.init
= nv04_display_init
;
104 engine
->display
.fini
= nv04_display_fini
;
105 engine
->pm
.clocks_get
= nv40_pm_clocks_get
;
106 engine
->pm
.clocks_pre
= nv40_pm_clocks_pre
;
107 engine
->pm
.clocks_set
= nv40_pm_clocks_set
;
108 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
109 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
110 engine
->pm
.temp_get
= nv40_temp_get
;
111 engine
->pm
.pwm_get
= nv40_pm_pwm_get
;
112 engine
->pm
.pwm_set
= nv40_pm_pwm_set
;
115 case 0x80: /* gotta love NVIDIA's consistency.. */
118 engine
->display
.early_init
= nv50_display_early_init
;
119 engine
->display
.late_takedown
= nv50_display_late_takedown
;
120 engine
->display
.create
= nv50_display_create
;
121 engine
->display
.destroy
= nv50_display_destroy
;
122 engine
->display
.init
= nv50_display_init
;
123 engine
->display
.fini
= nv50_display_fini
;
124 switch (dev_priv
->chipset
) {
135 engine
->pm
.clocks_get
= nv50_pm_clocks_get
;
136 engine
->pm
.clocks_pre
= nv50_pm_clocks_pre
;
137 engine
->pm
.clocks_set
= nv50_pm_clocks_set
;
140 engine
->pm
.clocks_get
= nva3_pm_clocks_get
;
141 engine
->pm
.clocks_pre
= nva3_pm_clocks_pre
;
142 engine
->pm
.clocks_set
= nva3_pm_clocks_set
;
145 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
146 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
147 if (dev_priv
->chipset
>= 0x84)
148 engine
->pm
.temp_get
= nv84_temp_get
;
150 engine
->pm
.temp_get
= nv40_temp_get
;
151 engine
->pm
.pwm_get
= nv50_pm_pwm_get
;
152 engine
->pm
.pwm_set
= nv50_pm_pwm_set
;
155 engine
->display
.early_init
= nv50_display_early_init
;
156 engine
->display
.late_takedown
= nv50_display_late_takedown
;
157 engine
->display
.create
= nv50_display_create
;
158 engine
->display
.destroy
= nv50_display_destroy
;
159 engine
->display
.init
= nv50_display_init
;
160 engine
->display
.fini
= nv50_display_fini
;
161 engine
->pm
.temp_get
= nv84_temp_get
;
162 engine
->pm
.clocks_get
= nvc0_pm_clocks_get
;
163 engine
->pm
.clocks_pre
= nvc0_pm_clocks_pre
;
164 engine
->pm
.clocks_set
= nvc0_pm_clocks_set
;
165 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
166 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
167 engine
->pm
.pwm_get
= nv50_pm_pwm_get
;
168 engine
->pm
.pwm_set
= nv50_pm_pwm_set
;
171 engine
->display
.early_init
= nouveau_stub_init
;
172 engine
->display
.late_takedown
= nouveau_stub_takedown
;
173 engine
->display
.create
= nvd0_display_create
;
174 engine
->display
.destroy
= nvd0_display_destroy
;
175 engine
->display
.init
= nvd0_display_init
;
176 engine
->display
.fini
= nvd0_display_fini
;
177 engine
->pm
.temp_get
= nv84_temp_get
;
178 engine
->pm
.clocks_get
= nvc0_pm_clocks_get
;
179 engine
->pm
.clocks_pre
= nvc0_pm_clocks_pre
;
180 engine
->pm
.clocks_set
= nvc0_pm_clocks_set
;
181 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
182 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
185 engine
->display
.early_init
= nouveau_stub_init
;
186 engine
->display
.late_takedown
= nouveau_stub_takedown
;
187 engine
->display
.create
= nvd0_display_create
;
188 engine
->display
.destroy
= nvd0_display_destroy
;
189 engine
->display
.init
= nvd0_display_init
;
190 engine
->display
.fini
= nvd0_display_fini
;
193 NV_ERROR(dev
, "NV%02x unsupported\n", dev_priv
->chipset
);
198 if (nouveau_modeset
== 2) {
199 engine
->display
.early_init
= nouveau_stub_init
;
200 engine
->display
.late_takedown
= nouveau_stub_takedown
;
201 engine
->display
.create
= nouveau_stub_init
;
202 engine
->display
.init
= nouveau_stub_init
;
203 engine
->display
.destroy
= nouveau_stub_takedown
;
210 nouveau_vga_set_decode(void *priv
, bool state
)
212 struct drm_device
*dev
= priv
;
213 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
215 if (dev_priv
->chipset
>= 0x40)
216 nv_wr32(dev
, 0x88054, state
);
218 nv_wr32(dev
, 0x1854, state
);
221 return VGA_RSRC_LEGACY_IO
| VGA_RSRC_LEGACY_MEM
|
222 VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
224 return VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
227 static void nouveau_switcheroo_set_state(struct pci_dev
*pdev
,
228 enum vga_switcheroo_state state
)
230 struct drm_device
*dev
= pci_get_drvdata(pdev
);
231 pm_message_t pmm
= { .event
= PM_EVENT_SUSPEND
};
232 if (state
== VGA_SWITCHEROO_ON
) {
233 printk(KERN_ERR
"VGA switcheroo: switched nouveau on\n");
234 dev
->switch_power_state
= DRM_SWITCH_POWER_CHANGING
;
235 nouveau_pci_resume(pdev
);
236 drm_kms_helper_poll_enable(dev
);
237 dev
->switch_power_state
= DRM_SWITCH_POWER_ON
;
239 printk(KERN_ERR
"VGA switcheroo: switched nouveau off\n");
240 dev
->switch_power_state
= DRM_SWITCH_POWER_CHANGING
;
241 drm_kms_helper_poll_disable(dev
);
242 nouveau_switcheroo_optimus_dsm();
243 nouveau_pci_suspend(pdev
, pmm
);
244 dev
->switch_power_state
= DRM_SWITCH_POWER_OFF
;
248 static void nouveau_switcheroo_reprobe(struct pci_dev
*pdev
)
250 struct drm_device
*dev
= pci_get_drvdata(pdev
);
251 nouveau_fbcon_output_poll_changed(dev
);
254 static bool nouveau_switcheroo_can_switch(struct pci_dev
*pdev
)
256 struct drm_device
*dev
= pci_get_drvdata(pdev
);
259 spin_lock(&dev
->count_lock
);
260 can_switch
= (dev
->open_count
== 0);
261 spin_unlock(&dev
->count_lock
);
265 static const struct vga_switcheroo_client_ops nouveau_switcheroo_ops
= {
266 .set_gpu_state
= nouveau_switcheroo_set_state
,
267 .reprobe
= nouveau_switcheroo_reprobe
,
268 .can_switch
= nouveau_switcheroo_can_switch
,
272 nouveau_card_init(struct drm_device
*dev
)
274 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
275 struct nouveau_engine
*engine
;
278 vga_client_register(dev
->pdev
, dev
, NULL
, nouveau_vga_set_decode
);
279 vga_switcheroo_register_client(dev
->pdev
, &nouveau_switcheroo_ops
);
281 /* Initialise internal driver API hooks */
282 ret
= nouveau_init_engine_ptrs(dev
);
285 engine
= &dev_priv
->engine
;
286 spin_lock_init(&dev_priv
->context_switch_lock
);
288 /* Make the CRTCs and I2C buses accessible */
289 ret
= engine
->display
.early_init(dev
);
293 /* Parse BIOS tables / Run init tables if card not POSTed */
294 ret
= nouveau_bios_init(dev
);
296 goto out_display_early
;
298 /* workaround an odd issue on nvc1 by disabling the device's
299 * nosnoop capability. hopefully won't cause issues until a
300 * better fix is found - assuming there is one...
302 if (dev_priv
->chipset
== 0xc1) {
303 nv_mask(dev
, 0x00088080, 0x00000800, 0x00000000);
306 ret
= nouveau_irq_init(dev
);
310 ret
= nouveau_display_create(dev
);
314 nouveau_backlight_init(dev
);
315 nouveau_pm_init(dev
);
317 if (dev
->mode_config
.num_crtc
) {
318 ret
= nouveau_display_init(dev
);
326 nouveau_pm_fini(dev
);
327 nouveau_backlight_exit(dev
);
328 nouveau_display_destroy(dev
);
330 nouveau_irq_fini(dev
);
332 nouveau_bios_takedown(dev
);
334 engine
->display
.late_takedown(dev
);
336 vga_switcheroo_unregister_client(dev
->pdev
);
337 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
341 static void nouveau_card_takedown(struct drm_device
*dev
)
343 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
344 struct nouveau_engine
*engine
= &dev_priv
->engine
;
346 if (dev
->mode_config
.num_crtc
)
347 nouveau_display_fini(dev
);
349 nouveau_pm_fini(dev
);
350 nouveau_backlight_exit(dev
);
351 nouveau_display_destroy(dev
);
353 if (dev_priv
->vga_ram
) {
354 nouveau_bo_unpin(dev_priv
->vga_ram
);
355 nouveau_bo_ref(NULL
, &dev_priv
->vga_ram
);
358 nouveau_bios_takedown(dev
);
359 engine
->display
.late_takedown(dev
);
361 nouveau_irq_fini(dev
);
363 vga_switcheroo_unregister_client(dev
->pdev
);
364 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
367 /* first module load, setup the mmio/fb mapping */
368 /* KMS: we need mmio at load time, not when the first drm client opens. */
369 int nouveau_firstopen(struct drm_device
*dev
)
374 /* if we have an OF card, copy vbios to RAMIN */
375 static void nouveau_OF_copy_vbios_to_ramin(struct drm_device
*dev
)
377 #if defined(__powerpc__)
379 const uint32_t *bios
;
380 struct device_node
*dn
= pci_device_to_OF_node(dev
->pdev
);
382 NV_INFO(dev
, "Unable to get the OF node\n");
386 bios
= of_get_property(dn
, "NVDA,BMP", &size
);
388 for (i
= 0; i
< size
; i
+= 4)
389 nv_wi32(dev
, i
, bios
[i
/4]);
390 NV_INFO(dev
, "OF bios successfully copied (%d bytes)\n", size
);
392 NV_INFO(dev
, "Unable to get the OF bios\n");
397 int nouveau_load(struct drm_device
*dev
, unsigned long flags
)
399 struct drm_nouveau_private
*dev_priv
;
400 uint32_t reg0
= ~0, strap
;
403 dev_priv
= kzalloc(sizeof(*dev_priv
), GFP_KERNEL
);
408 dev_priv
->newpriv
= dev
->dev_private
;
409 dev
->dev_private
= dev_priv
;
412 dev_priv
->flags
= flags
& NOUVEAU_FLAGS
;
414 NV_DEBUG(dev
, "vendor: 0x%X device: 0x%X class: 0x%X\n",
415 dev
->pci_vendor
, dev
->pci_device
, dev
->pdev
->class);
417 /* determine chipset and derive architecture from it */
418 reg0
= nv_rd32(dev
, NV03_PMC_BOOT_0
);
419 if ((reg0
& 0x0f000000) > 0) {
420 dev_priv
->chipset
= (reg0
& 0xff00000) >> 20;
421 switch (dev_priv
->chipset
& 0xf0) {
425 dev_priv
->card_type
= dev_priv
->chipset
& 0xf0;
429 dev_priv
->card_type
= NV_40
;
435 dev_priv
->card_type
= NV_50
;
438 dev_priv
->card_type
= NV_C0
;
441 dev_priv
->card_type
= NV_D0
;
444 dev_priv
->card_type
= NV_E0
;
450 if ((reg0
& 0xff00fff0) == 0x20004000) {
451 if (reg0
& 0x00f00000)
452 dev_priv
->chipset
= 0x05;
454 dev_priv
->chipset
= 0x04;
455 dev_priv
->card_type
= NV_04
;
458 if (!dev_priv
->card_type
) {
459 NV_ERROR(dev
, "unsupported chipset 0x%08x\n", reg0
);
464 NV_INFO(dev
, "Detected an NV%02x generation card (0x%08x)\n",
465 dev_priv
->card_type
, reg0
);
467 /* determine frequency of timing crystal */
468 strap
= nv_rd32(dev
, 0x101000);
469 if ( dev_priv
->chipset
< 0x17 ||
470 (dev_priv
->chipset
>= 0x20 && dev_priv
->chipset
<= 0x25))
476 case 0x00000000: dev_priv
->crystal
= 13500; break;
477 case 0x00000040: dev_priv
->crystal
= 14318; break;
478 case 0x00400000: dev_priv
->crystal
= 27000; break;
479 case 0x00400040: dev_priv
->crystal
= 25000; break;
482 NV_DEBUG(dev
, "crystal freq: %dKHz\n", dev_priv
->crystal
);
484 nouveau_OF_copy_vbios_to_ramin(dev
);
487 if (dev
->pci_device
== 0x01a0)
488 dev_priv
->flags
|= NV_NFORCE
;
489 else if (dev
->pci_device
== 0x01f0)
490 dev_priv
->flags
|= NV_NFORCE2
;
492 /* For kernel modesetting, init card now and bring up fbcon */
493 ret
= nouveau_card_init(dev
);
500 dev
->dev_private
= dev_priv
->newpriv
;
506 void nouveau_lastclose(struct drm_device
*dev
)
508 vga_switcheroo_process_delayed_switch();
511 int nouveau_unload(struct drm_device
*dev
)
513 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
515 nouveau_card_takedown(dev
);
517 dev
->dev_private
= dev_priv
->newpriv
;
522 /* Waits for PGRAPH to go completely idle */
523 bool nouveau_wait_for_idle(struct drm_device
*dev
)
525 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
528 if (dev_priv
->card_type
== NV_40
)
529 mask
&= ~NV40_PGRAPH_STATUS_SYNC_STALL
;
531 if (!nv_wait(dev
, NV04_PGRAPH_STATUS
, mask
, 0)) {
532 NV_ERROR(dev
, "PGRAPH idle timed out with status 0x%08x\n",
533 nv_rd32(dev
, NV04_PGRAPH_STATUS
));