randr12: common tmds access functions
[nouveau] / src / nv_output.c
1 /*
2  * Copyright 2006 Dave Airlie
3  * Copyright 2007 Maarten Maathuis
4  * Copyright 2007 Stuart Bennett
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  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 /*
26  * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
27  * decleration is at the bottom of this file as it is rather ugly 
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "xf86.h"
35 #include "os.h"
36 #include "mibank.h"
37 #include "globals.h"
38 #include "xf86.h"
39 #include "xf86Priv.h"
40 #include "xf86DDC.h"
41 #include "mipointer.h"
42 #include "windowstr.h"
43 #include <randrstr.h>
44 #include <X11/extensions/render.h>
45 #include "X11/Xatom.h"
46
47 #include "xf86Crtc.h"
48 #include "nv_include.h"
49
50 const char *OutputType[] = {
51     "None",
52     "VGA",
53     "DVI",
54     "LVDS",
55     "S-video",
56     "Composite",
57 };
58
59 const char *MonTypeName[7] = {
60     "AUTO",
61     "NONE",
62     "CRT",
63     "LVDS",
64     "TMDS",
65     "CTV",
66     "STV"
67 };
68
69 static int nv_output_ramdac_offset(xf86OutputPtr output)
70 {
71         NVOutputPrivatePtr nv_output = output->driver_private;
72         NVPtr pNv = NVPTR(output->scrn);
73         int offset = 0;
74
75         if (pNv->dcb_table.entry[nv_output->dcb_entry].or & 0xc)
76                 offset += 0x68;
77         if (pNv->dcb_table.entry[nv_output->dcb_entry].or & 0xa)
78                 offset += 0x2000;
79
80         return offset;
81 }
82
83 static Bool dpms_common(xf86OutputPtr output, int mode)
84 {
85         NVOutputPrivatePtr nv_output = output->driver_private;
86         NVPtr pNv = NVPTR(output->scrn);
87         xf86CrtcPtr crtc = output->crtc;
88         NVCrtcPrivatePtr nv_crtc;
89
90         if (nv_output->last_dpms == mode) /* Don't do unnecessary mode changes. */
91                 return FALSE;
92
93         nv_output->last_dpms = mode;
94
95         if (!crtc)      /* we need nv_crtc, so give up */
96                 return TRUE;
97         nv_crtc = crtc->driver_private;
98
99         if (pNv->NVArch >= 0x17 && pNv->twoHeads) {
100                 /* We may be going for modesetting, so we must reset our output binding */
101                 if (mode == DPMSModeOff) {
102                         NVWriteVgaCrtc5758(pNv, nv_crtc->head, 0, 0x7f);
103                         NVWriteVgaCrtc5758(pNv, nv_crtc->head, 2, 0);
104                 } else {
105                         NVWriteVgaCrtc5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
106                         NVWriteVgaCrtc5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
107                 }
108         }
109
110         return TRUE;
111 }
112
113 static void
114 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
115 {
116         ScrnInfoPtr pScrn = output->scrn;
117         NVPtr pNv = NVPTR(pScrn);
118         NVOutputPrivatePtr nv_output = output->driver_private;
119         xf86CrtcPtr crtc = output->crtc;
120         int oldmode = nv_output->last_dpms;
121
122         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_lvds_output_dpms is called with mode %d.\n", mode);
123
124         if (!dpms_common(output, mode))
125                 return;
126
127         if (crtc && pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_power_scripts) {
128                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
129                 int pclk = nv_get_clock_from_crtc(pScrn, &pNv->ModeReg, nv_crtc->head);
130
131                 switch (mode) {
132                 case DPMSModeStandby:
133                 case DPMSModeSuspend:
134                         call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_BACKLIGHT_OFF, pclk);
135                         break;
136                 case DPMSModeOff:
137                         call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_OFF, pclk);
138                         break;
139                 case DPMSModeOn:
140                         if (oldmode == DPMSModeStandby || oldmode == DPMSModeSuspend)
141                                 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_BACKLIGHT_ON, pclk);
142                         else
143                                 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_ON, pclk);
144                 default:
145                         break;
146                 }
147         }
148 }
149
150 static void
151 nv_analog_output_dpms(xf86OutputPtr output, int mode)
152 {
153         ScrnInfoPtr pScrn = output->scrn;
154         NVPtr pNv = NVPTR(output->scrn);
155
156         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_analog_output_dpms is called with mode %d.\n", mode);
157
158         dpms_common(output, mode);
159
160         if (pNv->twoHeads) {
161                 uint32_t outputval = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output));
162
163                 switch (mode) {
164                 case DPMSModeOff:
165                         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output),
166                                       outputval & ~NV_RAMDAC_OUTPUT_DAC_ENABLE);
167                         break;
168                 case DPMSModeOn:
169                         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output),
170                                       outputval | NV_RAMDAC_OUTPUT_DAC_ENABLE);
171                         break;
172                 }
173         }
174 }
175
176 static void
177 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
178 {
179         xf86CrtcPtr crtc = output->crtc;
180         ScrnInfoPtr pScrn = output->scrn;
181
182         xf86DrvMsg(pScrn->scrnIndex, X_INFO,"nv_tmds_output_dpms is called with mode %d.\n", mode);
183
184         if (!dpms_common(output, mode))
185                 return;
186
187         /* Are we assigned a ramdac already?, else we will be activated during mode set */
188         if (crtc) {
189                 NVPtr pNv = NVPTR(output->scrn);
190                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
191                 uint32_t fpcontrol = NVReadRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL);
192
193                 switch (mode) {
194                 case DPMSModeStandby:
195                 case DPMSModeSuspend:
196                 case DPMSModeOff:
197                         /* cut the TMDS output */           
198                         fpcontrol |= 0x20000022;
199                         break;
200                 case DPMSModeOn:
201                         /* disable cutting the TMDS output */
202                         fpcontrol &= ~0x20000022;
203                         break;
204                 }
205                 NVWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, fpcontrol);
206         }
207 }
208
209 static void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
210 {
211         NVPtr pNv = NVPTR(output->scrn);
212
213         /* This exists purely for proper text mode restore */
214         if (override && pNv->twoHeads) {
215                 NVOutputPrivatePtr nv_output = output->driver_private;
216
217                 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output), nv_output->restore_output);
218         }
219 }
220
221 static void
222 nv_output_save (xf86OutputPtr output)
223 {
224         ScrnInfoPtr pScrn = output->scrn;
225         NVPtr pNv = NVPTR(pScrn);
226         NVOutputPrivatePtr nv_output = output->driver_private;
227         NVOutputRegPtr regp = &pNv->SavedReg.dac_reg[nv_output->preferred_output];
228
229         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_save is called.\n");
230
231         if (pNv->twoHeads)
232                 nv_output->restore_output = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output));
233
234         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
235                 int i;
236
237                 /* Store the registers for helping with VT restore */
238                 for (i = 0; i < 0xFF; i++)
239                         regp->TMDS[i] = nv_dcb_read_tmds(pNv, nv_output->dcb_entry, 0, i);
240         }
241 }
242
243 uint32_t nv_get_clock_from_crtc(ScrnInfoPtr pScrn, RIVA_HW_STATE *state, uint8_t crtc)
244 {
245         NVPtr pNv = NVPTR(pScrn);
246         Bool vpllb_disabled = FALSE;
247         uint32_t vplla = crtc ? state->vpll2_a : state->vpll1_a;
248         uint32_t vpllb = crtc ? state->vpll2_b : state->vpll1_b;
249         uint8_t m1, m2, n1, n2, p;
250
251         if (!pNv->twoStagePLL)
252                 vpllb_disabled = TRUE;
253
254         /* This is the dummy value nvidia sets when vpll is disabled */
255         if ((vpllb & 0xFFFF) == 0x11F)
256                 vpllb_disabled = TRUE;
257
258         if (!(vpllb & NV31_RAMDAC_ENABLE_VCO2) && pNv->NVArch != 0x30)
259                 vpllb_disabled = TRUE;
260
261         if (!(vplla & NV30_RAMDAC_ENABLE_VCO2) && pNv->NVArch == 0x30)
262                 vpllb_disabled = TRUE;
263
264         if (pNv->NVArch == 0x30) {
265                 m1 = vplla & 0x7;
266                 n1 = (vplla >> 8) & 0xFF;
267                 p = (vplla >> 16) & 0x7;
268         } else {
269                 m1 = vplla & 0xFF;
270                 n1 = (vplla >> 8) & 0xFF;
271                 p = (vplla >> 16) & 0x7;
272         }
273
274         if (vpllb_disabled) {
275                 m2 = 1;
276                 n2 = 1;
277         } else {
278                 if (pNv->NVArch == 0x30) {
279                         m2 = (vplla >> 4) & 0x7;
280                         n2 = ((vplla >> 19) & 0x7) | (((vplla >> 24) & 0x3) << 3);
281                 } else {
282                         m2 = vpllb & 0xFF;
283                         n2 = (vpllb >> 8) & 0xFF;
284                 }
285         }
286
287         /* avoid div by 0, if used on pNv->ModeReg before ModeReg set up */
288         if (!m1 || !m2)
289                 return 0;
290
291         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "The clock seems to be %d kHz.\n", (uint32_t)((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p);
292         return ((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p;
293 }
294
295 uint32_t nv_calc_tmds_clock_from_pll(xf86OutputPtr output)
296 {
297         ScrnInfoPtr pScrn = output->scrn;
298         NVPtr pNv = NVPTR(pScrn);
299         RIVA_HW_STATE *state = &pNv->SavedReg;
300         NVOutputPrivatePtr nv_output = output->driver_private;
301
302         /* Registers are stored by their preferred ramdac */
303         /* So or = 3 still means it uses the "ramdac0" regs. */
304         NVOutputRegPtr regp = &state->dac_reg[nv_output->preferred_output];
305
306         /* Bit3 swaps crtc (clocks are bound to crtc) and output */
307         Bool swapped_clock = !!(regp->TMDS[0x4] & (1 << 3));
308         uint8_t vpll_num = swapped_clock ^ nv_output->preferred_output;
309
310         return nv_get_clock_from_crtc(pScrn, state, vpll_num);
311 }
312
313 void nv_set_tmds_registers(xf86OutputPtr output, uint32_t clock, Bool override, Bool crosswired)
314 {
315         ScrnInfoPtr pScrn = output->scrn;
316         NVPtr pNv = NVPTR(pScrn);
317         NVOutputPrivatePtr nv_output = output->driver_private;
318         xf86CrtcPtr crtc = output->crtc;
319         /* We have no crtc, so what are we supposed to do now? */
320         /* This can only happen during VT restore */
321         if (crtc && !override) {
322                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
323                 /*
324                  * Resetting all registers is a bad idea, it seems to work fine without it.
325                  */
326                 if (nv_output->type == OUTPUT_TMDS)
327                         run_tmds_table(pScrn, nv_output->dcb_entry, nv_crtc->head, clock);
328                 /* on panels where we do reset after pclk change, DPMS on will do this */
329                 else if (!pNv->VBIOS.fp.reset_after_pclk_change)
330                         call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_RESET, clock);
331         } else {
332                 /*
333                  * We have no crtc, but we do know what output we are and if we were crosswired.
334                  * We can determine our crtc from this.
335                  */
336                 if (nv_output->type == OUTPUT_TMDS)
337                         run_tmds_table(pScrn, nv_output->dcb_entry, nv_output->preferred_output ^ crosswired, clock);
338                 else {
339                         if (!pNv->VBIOS.fp.reset_after_pclk_change)
340                                 call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_RESET, clock);
341                         call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_PANEL_ON, clock);
342                 }
343         }
344 }
345
346 static void
347 nv_output_restore (xf86OutputPtr output)
348 {
349         ScrnInfoPtr pScrn = output->scrn;
350         NVPtr pNv = NVPTR(pScrn);
351         RIVA_HW_STATE *state;
352         NVOutputPrivatePtr nv_output = output->driver_private;
353         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_restore is called.\n");
354
355         state = &pNv->SavedReg;
356
357         /* Due to strange mapping of outputs we could have swapped analog and digital */
358         /* So we force load all the registers */
359         nv_output_load_state_ext(output, state, TRUE);
360
361         nv_output->last_dpms = NV_DPMS_CLEARED;
362 }
363
364 static int
365 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
366 {
367         if (pMode->Flags & V_DBLSCAN)
368                 return MODE_NO_DBLESCAN;
369
370         if (pMode->Clock > 400000 || pMode->Clock < 25000)
371                 return MODE_CLOCK_RANGE;
372
373         return MODE_OK;
374 }
375
376
377 static Bool
378 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
379                      DisplayModePtr adjusted_mode)
380 {
381         NVOutputPrivatePtr nv_output = output->driver_private;
382         ScrnInfoPtr pScrn = output->scrn;
383
384         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_mode_fixup is called.\n");
385
386         /* For internal panels and gpu scaling on DVI we need the native mode */
387         if ((nv_output->type == OUTPUT_LVDS || (nv_output->type == OUTPUT_TMDS && nv_output->scaling_mode != SCALE_PANEL))) {
388                 adjusted_mode->HDisplay = nv_output->native_mode->HDisplay;
389                 adjusted_mode->HSkew = nv_output->native_mode->HSkew;
390                 adjusted_mode->HSyncStart = nv_output->native_mode->HSyncStart;
391                 adjusted_mode->HSyncEnd = nv_output->native_mode->HSyncEnd;
392                 adjusted_mode->HTotal = nv_output->native_mode->HTotal;
393                 adjusted_mode->VDisplay = nv_output->native_mode->VDisplay;
394                 adjusted_mode->VScan = nv_output->native_mode->VScan;
395                 adjusted_mode->VSyncStart = nv_output->native_mode->VSyncStart;
396                 adjusted_mode->VSyncEnd = nv_output->native_mode->VSyncEnd;
397                 adjusted_mode->VTotal = nv_output->native_mode->VTotal;
398                 adjusted_mode->Clock = nv_output->native_mode->Clock;
399                 adjusted_mode->Flags = nv_output->native_mode->Flags;
400
401                 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
402         }
403
404         return TRUE;
405 }
406
407 #if 0
408 static void
409 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
410 {
411         NVOutputPrivatePtr nv_output = output->driver_private;
412         ScrnInfoPtr pScrn = output->scrn;
413         //RIVA_HW_STATE *state;
414         //NVOutputRegPtr regp, savep;
415 }
416 #endif
417
418 static void
419 nv_output_mode_set_routing(xf86OutputPtr output, Bool bios_restore)
420 {
421         ScrnInfoPtr pScrn = output->scrn;
422         NVPtr pNv = NVPTR(pScrn);
423
424         if (pNv->twoHeads) {
425                 NVOutputPrivatePtr nv_output = output->driver_private;
426                 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
427                 uint32_t outputval = 0;
428
429                 if (nv_output->type == OUTPUT_ANALOG)
430                         /* bit 16-19 are bits that are set on some G70 cards,
431                          * but don't seem to have much effect */
432                         outputval = nv_crtc->head << 8 | NV_RAMDAC_OUTPUT_DAC_ENABLE;
433
434                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV_RAMDAC_OUTPUT: 0x%X\n", outputval);
435
436                 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + nv_output_ramdac_offset(output), outputval);
437         }
438
439         /* This could use refinement for flatpanels, but it should work this way */
440         if (pNv->NVArch < 0x44)
441                 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(output), 0xf0000000);
442         else
443                 NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + nv_output_ramdac_offset(output), 0x00100000);
444 }
445
446 static void
447 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
448                    DisplayModePtr adjusted_mode)
449 {
450         ScrnInfoPtr pScrn = output->scrn;
451         NVPtr pNv = NVPTR(pScrn);
452         NVOutputPrivatePtr nv_output = output->driver_private;
453         RIVA_HW_STATE *state;
454
455         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_mode_set is called.\n");
456
457         state = &pNv->ModeReg;
458
459         //nv_output_mode_set_regs(output, mode, adjusted_mode);
460         nv_output_load_state_ext(output, state, FALSE);
461         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
462                 nv_set_tmds_registers(output, adjusted_mode->Clock, FALSE, FALSE);
463
464         nv_output_mode_set_routing(output, NVMatchModePrivate(mode, NV_MODE_CONSOLE));
465 }
466
467 static xf86MonPtr
468 nv_get_edid(xf86OutputPtr output)
469 {
470         NVOutputPrivatePtr nv_output = output->driver_private;
471         xf86MonPtr ddc_mon;
472
473         if (nv_output->pDDCBus == NULL)
474                 return NULL;
475
476         ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
477         if (!ddc_mon)
478                 return NULL;
479
480         if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
481                 goto invalid;
482
483         if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
484                                 nv_output->type == OUTPUT_LVDS))
485                 goto invalid;
486
487         return ddc_mon;
488
489 invalid:
490         xfree(ddc_mon);
491         return NULL;
492 }
493
494 static Bool
495 nv_ddc_detect(xf86OutputPtr output)
496 {
497         xf86MonPtr m = nv_get_edid(output);
498
499         if (m == NULL)
500                 return FALSE;
501
502         xfree(m);
503         return TRUE;
504 }
505
506 static Bool
507 nv_load_detect(xf86OutputPtr output)
508 {
509         ScrnInfoPtr pScrn = output->scrn;
510         NVOutputPrivatePtr nv_output = output->driver_private;
511         NVPtr pNv = NVPTR(pScrn);
512         uint32_t testval, regoffset = nv_output_ramdac_offset(output);
513         uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, temp;
514         int present = 0;
515
516 #define RGB_TEST_DATA(r,g,b) (r << 0 | g << 10 | b << 20)
517         testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
518         if (pNv->VBIOS.dactestval)
519                 testval = pNv->VBIOS.dactestval;
520
521         saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset);
522         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl & ~0x00010000);
523
524         if (pNv->NVArch >= 0x17) {
525                 saved_powerctrl_2 = nvReadMC(pNv, NV_PBUS_POWERCTRL_2);
526
527                 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
528                 if (regoffset == 0x68) {
529                         saved_powerctrl_4 = nvReadMC(pNv, NV_PBUS_POWERCTRL_4);
530                         nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
531                 }
532         }
533
534         usleep(4000);
535
536         saved_routput = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset);
537         /* nv driver and nv31 use 0xfffffeee
538          * nv34 and 6600 use 0xfffffece */
539         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, saved_routput & 0xfffffece);
540         usleep(1000);
541
542         temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset);
543         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, temp | 1);
544
545         /* no regoffset on purpose */
546         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_DATA, 1 << 31 | testval);
547         temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL);
548         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
549         usleep(1000);
550
551         present = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset) & (1 << 28);
552
553         /* no regoffset on purpose */
554         temp = NVReadRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL);
555         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL, temp & 0xffffefff);
556         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_DATA, 0);
557
558         /* bios does something more complex for restoring, but I think this is good enough */
559         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT + regoffset, saved_routput);
560         NVWriteRAMDAC(pNv, 0, NV_RAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
561         if (pNv->NVArch >= 0x17) {
562                 if (regoffset == 0x68)
563                         nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
564                 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
565         }
566
567         if (present) {
568                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Load detected on output %d\n", nv_output->preferred_output);
569                 return TRUE;
570         }
571
572         return FALSE;
573 }
574
575 static xf86OutputStatus
576 nv_tmds_output_detect(xf86OutputPtr output)
577 {
578         ScrnInfoPtr pScrn = output->scrn;
579
580         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_tmds_output_detect is called.\n");
581
582         if (nv_ddc_detect(output))
583                 return XF86OutputStatusConnected;
584
585         return XF86OutputStatusDisconnected;
586 }
587
588
589 static xf86OutputStatus
590 nv_analog_output_detect(xf86OutputPtr output)
591 {
592         ScrnInfoPtr pScrn = output->scrn;
593         NVPtr pNv = NVPTR(pScrn);
594
595         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_analog_output_detect is called.\n");
596
597         if (nv_ddc_detect(output))
598                 return XF86OutputStatusConnected;
599
600         /* we don't have a load det function for early cards */
601         if (!pNv->twoHeads || pNv->NVArch == 0x11)
602                 return XF86OutputStatusUnknown;
603         else if (pNv->twoHeads && nv_load_detect(output))
604                 return XF86OutputStatusConnected;
605
606         return XF86OutputStatusDisconnected;
607 }
608
609 static DisplayModePtr
610 nv_output_get_modes(xf86OutputPtr output, xf86MonPtr mon)
611 {
612         ScrnInfoPtr pScrn = output->scrn;
613         NVOutputPrivatePtr nv_output = output->driver_private;
614         DisplayModePtr ddc_modes;
615
616         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_get_modes is called.\n");
617
618         xf86OutputSetEDID(output, mon);
619
620         ddc_modes = xf86OutputGetEDIDModes(output);
621
622         if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
623                 int i;
624                 DisplayModePtr mode;
625
626                 for (i = 0; i < DET_TIMINGS; i++) {
627                         /* We only look at detailed timings atm */
628                         if (mon->det_mon[i].type != DT)
629                                 continue;
630                         /* Selecting only based on width ok? */
631                         if (mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
632                                 nv_output->fpWidth = mon->det_mon[i].section.d_timings.h_active;
633                                 nv_output->fpHeight = mon->det_mon[i].section.d_timings.v_active;
634                         }
635                 }
636                 if (!(nv_output->fpWidth && nv_output->fpHeight)) {
637                         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No EDID detailed timings available, bailing out.\n");
638                         return NULL;
639                 }
640
641                 if (nv_output->native_mode)
642                         xfree(nv_output->native_mode);
643
644                 /* Prefer ddc modes. */
645                 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
646                         if (mode->HDisplay == nv_output->fpWidth &&
647                                 mode->VDisplay == nv_output->fpHeight) {
648                                 /* Take the preferred mode when it exists. */
649                                 if (mode->type & M_T_PREFERRED) {
650                                         nv_output->native_mode = xf86DuplicateMode(mode);
651                                         break;
652                                 }
653                                 /* Find the highest refresh mode otherwise. */
654                                 if (!nv_output->native_mode || (mode->VRefresh > nv_output->native_mode->VRefresh)) {
655                                         mode->type |= M_T_PREFERRED;
656                                         nv_output->native_mode = xf86DuplicateMode(mode);
657                                 }
658                         }
659                 }
660         }
661
662         if (nv_output->type == OUTPUT_LVDS)
663                 setup_edid_dual_link_lvds(pScrn, nv_output->native_mode->Clock);
664
665         return ddc_modes;
666 }
667
668 static DisplayModePtr
669 nv_output_get_ddc_modes(xf86OutputPtr output)
670 {
671         xf86MonPtr ddc_mon;
672         ScrnInfoPtr pScrn = output->scrn;
673
674         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_get_ddc_modes is called.\n");
675
676         ddc_mon = nv_get_edid(output);
677
678         if (ddc_mon == NULL)
679                 return NULL;
680
681         return nv_output_get_modes(output, ddc_mon);
682 }
683
684 static void
685 nv_output_destroy (xf86OutputPtr output)
686 {
687         NVOutputPrivatePtr nv_output = output->driver_private;
688         ScrnInfoPtr pScrn = output->scrn;
689
690         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_destroy is called.\n");
691
692         if (nv_output) {
693                 if (nv_output->native_mode)
694                         xfree(nv_output->native_mode);
695                 xfree(output->driver_private);
696         }
697 }
698
699 static void
700 nv_output_prepare(xf86OutputPtr output)
701 {
702         ScrnInfoPtr pScrn = output->scrn;
703         //xf86CrtcPtr crtc = output->crtc;
704         //NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
705         //Bool quirk_mode = FALSE;
706
707         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_prepare is called.\n");
708
709         output->funcs->dpms(output, DPMSModeOff);
710
711 /* This quirk has weird sideeffects on NV36M, so disable it. */
712 /* Remove later (a month or two) on if it proves to be unneeded. */
713 /* Date: 8 March 2008 */
714 #if 0
715         /* Quirk for strange dual link laptops. */
716         if ((nv_output->output_resource == 1) && (or == 3)) {
717                 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
718                         /* Observed on a NV31M, some regs are claimed by one output/crtc. */
719                         if (nv_crtc->head == 1) {
720                                 pNv->fp_regs_owner[0] = 1;
721                                 pNv->fp_regs_owner[1] = 1;
722                                 quirk_mode = TRUE;
723                         }
724                 }
725         }
726
727         /* If a normal tmds or lvds comes by, we better reset this, otherwise messy things might happen. */
728         if (!quirk_mode && (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)) {
729                 pNv->fp_regs_owner[0] = 0;
730                 pNv->fp_regs_owner[1] = 1;
731         }
732 #endif
733 }
734
735 static void
736 nv_output_commit(xf86OutputPtr output)
737 {
738         ScrnInfoPtr pScrn = output->scrn;
739         xf86CrtcPtr crtc = output->crtc;
740
741         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_output_commit is called.\n");
742
743         if (crtc) {
744                 NVOutputPrivatePtr nv_output = output->driver_private;
745                 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
746                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Output %s is running on CRTC %d using output resource %d.\n", output->name, nv_crtc->head, nv_output->preferred_output);
747         }
748
749         output->funcs->dpms(output, DPMSModeOn);
750 }
751
752 static const xf86OutputFuncsRec nv_analog_output_funcs = {
753     .dpms = nv_analog_output_dpms,
754     .save = nv_output_save,
755     .restore = nv_output_restore,
756     .mode_valid = nv_output_mode_valid,
757     .mode_fixup = nv_output_mode_fixup,
758     .mode_set = nv_output_mode_set,
759     .detect = nv_analog_output_detect,
760     .get_modes = nv_output_get_ddc_modes,
761     .destroy = nv_output_destroy,
762     .prepare = nv_output_prepare,
763     .commit = nv_output_commit,
764 };
765
766 /*
767  * Several scaling modes exist, let the user choose.
768  */
769 #define SCALING_MODE_NAME "SCALING_MODE"
770 static const struct {
771         char *name;
772         enum scaling_modes mode;
773 } scaling_mode[] = {
774         { "panel", SCALE_PANEL },
775         { "fullscreen", SCALE_FULLSCREEN },
776         { "aspect", SCALE_ASPECT },
777         { "noscale", SCALE_NOSCALE },
778         { NULL, SCALE_INVALID}
779 };
780 static Atom scaling_mode_atom;
781
782 static int
783 nv_scaling_mode_lookup(char *name, int size)
784 {
785         int i;
786
787         /* for when name is zero terminated */
788         if (size < 0)
789                 size = strlen(name);
790
791         for (i = 0; scaling_mode[i].name; i++)
792                 /* We're getting non-terminated strings */
793                 if (strlen(scaling_mode[i].name) >= size &&
794                                 !strncasecmp(name, scaling_mode[i].name, size))
795                         break;
796
797         return scaling_mode[i].mode;
798 }
799
800 static void
801 nv_digital_output_create_resources(xf86OutputPtr output)
802 {
803         NVOutputPrivatePtr nv_output = output->driver_private;
804         ScrnInfoPtr pScrn = output->scrn;
805         int error, i;
806
807         /*
808          * Setup scaling mode property.
809          */
810         scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
811
812         error = RRConfigureOutputProperty(output->randr_output,
813                                         scaling_mode_atom, TRUE, FALSE, FALSE,
814                                         0, NULL);
815
816         if (error != 0) {
817                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
818                         "RRConfigureOutputProperty error, %d\n", error);
819         }
820
821         char *existing_scale_name = NULL;
822         for (i = 0; scaling_mode[i].name; i++)
823                 if (scaling_mode[i].mode == nv_output->scaling_mode)
824                         existing_scale_name = scaling_mode[i].name;
825
826         error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
827                                         XA_STRING, 8, PropModeReplace, 
828                                         strlen(existing_scale_name),
829                                         existing_scale_name, FALSE, TRUE);
830
831         if (error != 0) {
832                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
833                         "Failed to set scaling mode, %d\n", error);
834         }
835 }
836
837 static Bool
838 nv_digital_output_set_property(xf86OutputPtr output, Atom property,
839                                 RRPropertyValuePtr value)
840 {
841         NVOutputPrivatePtr nv_output = output->driver_private;
842
843         if (property == scaling_mode_atom) {
844                 int32_t ret;
845                 char *name = NULL;
846
847                 if (value->type != XA_STRING || value->format != 8)
848                         return FALSE;
849
850                 name = (char *) value->data;
851
852                 /* Match a string to a scaling mode */
853                 ret = nv_scaling_mode_lookup(name, value->size);
854                 if (ret == SCALE_INVALID)
855                         return FALSE;
856
857                 /* LVDS must always use gpu scaling. */
858                 if (ret == SCALE_PANEL && nv_output->type == OUTPUT_LVDS)
859                         return FALSE;
860
861                 nv_output->scaling_mode = ret;
862                 return TRUE;
863         }
864
865         return TRUE;
866 }
867
868 static int 
869 nv_tmds_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
870 {
871         ScrnInfoPtr pScrn = output->scrn;
872         NVPtr pNv = NVPTR(pScrn);
873         NVOutputPrivatePtr nv_output = output->driver_private;
874
875         /* We can't exceed the native mode.*/
876         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
877                 return MODE_PANEL;
878
879         if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible) {
880                 if (pMode->Clock > 330000) /* 2x165 MHz */
881                         return MODE_CLOCK_RANGE;
882         } else {
883                 if (pMode->Clock > 165000) /* 165 MHz */
884                         return MODE_CLOCK_RANGE;
885         }
886
887         return nv_output_mode_valid(output, pMode);
888 }
889
890 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
891         .dpms = nv_tmds_output_dpms,
892         .save = nv_output_save,
893         .restore = nv_output_restore,
894         .mode_valid = nv_tmds_output_mode_valid,
895         .mode_fixup = nv_output_mode_fixup,
896         .mode_set = nv_output_mode_set,
897         .detect = nv_tmds_output_detect,
898         .get_modes = nv_output_get_ddc_modes,
899         .destroy = nv_output_destroy,
900         .prepare = nv_output_prepare,
901         .commit = nv_output_commit,
902         .create_resources = nv_digital_output_create_resources,
903         .set_property = nv_digital_output_set_property,
904 };
905
906 static int nv_lvds_output_mode_valid
907 (xf86OutputPtr output, DisplayModePtr pMode)
908 {
909         NVOutputPrivatePtr nv_output = output->driver_private;
910
911         /* No modes > panel's native res */
912         if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
913                 return MODE_PANEL;
914
915         return nv_output_mode_valid(output, pMode);
916 }
917
918 static xf86OutputStatus
919 nv_lvds_output_detect(xf86OutputPtr output)
920 {
921         ScrnInfoPtr pScrn = output->scrn;
922         NVPtr pNv = NVPTR(pScrn);
923         NVOutputPrivatePtr nv_output = output->driver_private;
924
925         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_lvds_output_detect is called.\n");
926
927         if (nv_ddc_detect(output))
928                 return XF86OutputStatusConnected;
929         if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode &&
930             pNv->VBIOS.fp.native_mode)
931                 return XF86OutputStatusConnected;
932         if (pNv->VBIOS.fp.edid)
933                 return XF86OutputStatusConnected;
934
935         return XF86OutputStatusDisconnected;
936 }
937
938 static DisplayModePtr
939 nv_lvds_output_get_modes(xf86OutputPtr output)
940 {
941         ScrnInfoPtr pScrn = output->scrn;
942         NVPtr pNv = NVPTR(pScrn);
943         NVOutputPrivatePtr nv_output = output->driver_private;
944         DisplayModePtr modes;
945
946         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_lvds_output_get_modes is called.\n");
947
948         if ((modes = nv_output_get_ddc_modes(output)))
949                 return modes;
950
951         if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode ||
952             (pNv->VBIOS.fp.native_mode == NULL)) {
953                 xf86MonPtr edid_mon;
954
955                 if (!pNv->VBIOS.fp.edid)
956                         return NULL;
957
958                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using hardcoded BIOS FP EDID\n");
959                 edid_mon = xf86InterpretEDID(pScrn->scrnIndex, pNv->VBIOS.fp.edid);
960                 return nv_output_get_modes(output, edid_mon);
961         }
962
963         nv_output->fpWidth = pNv->VBIOS.fp.native_mode->HDisplay;
964         nv_output->fpHeight = pNv->VBIOS.fp.native_mode->VDisplay;
965
966         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
967                 nv_output->fpWidth, nv_output->fpHeight);
968
969         nv_output->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
970
971         return xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
972 }
973
974 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
975         .dpms = nv_lvds_output_dpms,
976         .save = nv_output_save,
977         .restore = nv_output_restore,
978         .mode_valid = nv_lvds_output_mode_valid,
979         .mode_fixup = nv_output_mode_fixup,
980         .mode_set = nv_output_mode_set,
981         .detect = nv_lvds_output_detect,
982         .get_modes = nv_lvds_output_get_modes,
983         .destroy = nv_output_destroy,
984         .prepare = nv_output_prepare,
985         .commit = nv_output_commit,
986         .create_resources = nv_digital_output_create_resources,
987         .set_property = nv_digital_output_set_property,
988 };
989
990 static void nv_add_output(ScrnInfoPtr pScrn, int dcb_entry, const xf86OutputFuncsRec *output_funcs, char *outputname)
991 {
992         NVPtr pNv = NVPTR(pScrn);
993         xf86OutputPtr output;
994         NVOutputPrivatePtr nv_output;
995
996         int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
997         if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
998                 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
999
1000         if (!(output = xf86OutputCreate(pScrn, output_funcs, outputname)))
1001                 return;
1002
1003         if (!(nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1)))
1004                 return;
1005
1006         output->driver_private = nv_output;
1007
1008         nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1009         nv_output->dcb_entry = dcb_entry;
1010         nv_output->type = pNv->dcb_table.entry[dcb_entry].type;
1011         nv_output->last_dpms = NV_DPMS_CLEARED;
1012
1013         /* output route:
1014          * bit0: OUTPUT_0 valid
1015          * bit1: OUTPUT_1 valid
1016          * So lowest order has highest priority.
1017          * Below is guesswork:
1018          * bit2: All outputs valid
1019          */
1020         /* We choose the preferred output resource initially. */
1021         if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1)
1022                 nv_output->preferred_output = 1;
1023         else
1024                 nv_output->preferred_output = 0;
1025
1026         if (nv_output->type == OUTPUT_LVDS || nv_output->type == OUTPUT_TMDS) {
1027                 if (pNv->fpScaler) /* GPU Scaling */
1028                         nv_output->scaling_mode = SCALE_ASPECT;
1029                 else /* Panel scaling */
1030                         nv_output->scaling_mode = SCALE_PANEL;
1031
1032                 if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
1033                         nv_output->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
1034                         if (nv_output->scaling_mode == SCALE_INVALID)
1035                                 nv_output->scaling_mode = SCALE_ASPECT; /* default */
1036                 }
1037         }
1038
1039         output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1040
1041         xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Added output %s\n", outputname);
1042 }
1043
1044 void NvSetupOutputs(ScrnInfoPtr pScrn)
1045 {
1046         NVPtr pNv = NVPTR(pScrn);
1047         int i, type, i2c_count[0xf];
1048         char outputname[20];
1049         int vga_count = 0, tv_count = 0, dvia_count = 0, dvid_count = 0, lvds_count = 0;
1050
1051         memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1052         memset(i2c_count, 0, sizeof(i2c_count));
1053         for (i = 0 ; i < pNv->dcb_table.entries; i++)
1054                 i2c_count[pNv->dcb_table.entry[i].i2c_index]++;
1055
1056         /* we setup the outputs up from the BIOS table */
1057         for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1058                 type = pNv->dcb_table.entry[i].type;
1059
1060                 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry %d: type: %d, i2c_index: %d, heads: %d, bus: %d, or: %d\n", i, type, pNv->dcb_table.entry[i].i2c_index, pNv->dcb_table.entry[i].heads, pNv->dcb_table.entry[i].bus, pNv->dcb_table.entry[i].or);
1061
1062                 switch (type) {
1063                 case OUTPUT_ANALOG:
1064                         if (i2c_count[pNv->dcb_table.entry[i].i2c_index] == 1)
1065                                 sprintf(outputname, "VGA-%d", vga_count++);
1066                         else
1067                                 sprintf(outputname, "DVI-A-%d", dvia_count++);
1068                         nv_add_output(pScrn, i, &nv_analog_output_funcs, outputname);
1069                         break;
1070                 case OUTPUT_TMDS:
1071                         sprintf(outputname, "DVI-D-%d", dvid_count++);
1072                         nv_add_output(pScrn, i, &nv_tmds_output_funcs, outputname);
1073                         break;
1074                 case OUTPUT_TV:
1075                         sprintf(outputname, "TV-%d", tv_count++);
1076 //                      nv_add_output(pScrn, i, &nv_tv_output_funcs, outputname);
1077                         break;
1078                 case OUTPUT_LVDS:
1079                         sprintf(outputname, "LVDS-%d", lvds_count++);
1080                         nv_add_output(pScrn, i, &nv_lvds_output_funcs, outputname);
1081                         break;
1082                 default:
1083                         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1084                         break;
1085                 }
1086         }
1087 }
1088
1089 /*************************************************************************** \
1090 |*                                                                           *|
1091 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1092 |*                                                                           *|
1093 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1094 |*     international laws.  Users and possessors of this source code are     *|
1095 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1096 |*     use this code in individual and commercial software.                  *|
1097 |*                                                                           *|
1098 |*     Any use of this source code must include,  in the user documenta-     *|
1099 |*     tion and  internal comments to the code,  notices to the end user     *|
1100 |*     as follows:                                                           *|
1101 |*                                                                           *|
1102 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1103 |*                                                                           *|
1104 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1105 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1106 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1107 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1108 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1109 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1110 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1111 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1112 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1113 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1114 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1115 |*                                                                           *|
1116 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1117 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1118 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1119 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1120 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1121 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1122 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1123 |*     all U.S. Government End Users  acquire the source code  with only     *|
1124 |*     those rights set forth herein.                                        *|
1125 |*                                                                           *|
1126  \***************************************************************************/