2 * Copyright 2006 Dave Airlie
3 * Copyright 2007 Maarten Maathuis
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
26 * decleration is at the bottom of this file as it is rather ugly
40 #include "mipointer.h"
41 #include "windowstr.h"
43 #include <X11/extensions/render.h>
44 #include "X11/Xatom.h"
47 #include "nv_include.h"
49 const char *OutputType[] = {
58 const char *MonTypeName[7] = {
69 * TMDS registers are indirect 8 bit registers.
70 * Reading is straightforward, writing a bit odd.
71 * Reading: Write adress (+write protect bit, do not forget this), then read value.
72 * Writing: Write adress (+write protect bit), write value, write adress again and write it again (+write protect bit).
75 void NVWriteTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
77 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
78 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
80 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA, val & 0xff);
82 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL, tmds_reg & 0xff);
83 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
84 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
87 CARD8 NVReadTMDS(NVPtr pNv, int ramdac, CARD32 tmds_reg)
89 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
90 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
92 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0xff);
95 /* Two register sets exist, this one is only used for dual link dvi/lvds */
97 void NVWriteTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg, CARD32 val)
99 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
100 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
102 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2, val & 0xff);
104 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2, tmds_reg & 0xff);
105 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
106 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
109 CARD8 NVReadTMDS2(NVPtr pNv, int ramdac, CARD32 tmds_reg)
111 nvWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL_2,
112 (tmds_reg & 0xff) | NV_RAMDAC_FP_TMDS_CONTROL_2_WRITE_DISABLE);
114 return (nvReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA_2) & 0xff);
117 void NVOutputWriteTMDS(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
119 NVOutputPrivatePtr nv_output = output->driver_private;
120 ScrnInfoPtr pScrn = output->scrn;
121 NVPtr pNv = NVPTR(pScrn);
123 /* We must write to the "bus" of the output */
124 NVWriteTMDS(pNv, nv_output->preferred_output, tmds_reg, val);
127 CARD8 NVOutputReadTMDS(xf86OutputPtr output, CARD32 tmds_reg)
129 NVOutputPrivatePtr nv_output = output->driver_private;
130 ScrnInfoPtr pScrn = output->scrn;
131 NVPtr pNv = NVPTR(pScrn);
133 /* We must read from the "bus" of the output */
134 return NVReadTMDS(pNv, nv_output->preferred_output, tmds_reg);
137 void NVOutputWriteTMDS2(xf86OutputPtr output, CARD32 tmds_reg, CARD32 val)
139 NVOutputPrivatePtr nv_output = output->driver_private;
140 ScrnInfoPtr pScrn = output->scrn;
141 NVPtr pNv = NVPTR(pScrn);
143 /* We must write to the "bus" of the output */
144 NVWriteTMDS2(pNv, nv_output->preferred_output, tmds_reg, val);
147 CARD8 NVOutputReadTMDS2(xf86OutputPtr output, CARD32 tmds_reg)
149 NVOutputPrivatePtr nv_output = output->driver_private;
150 ScrnInfoPtr pScrn = output->scrn;
151 NVPtr pNv = NVPTR(pScrn);
153 /* We must read from the "bus" of the output */
154 return NVReadTMDS2(pNv, nv_output->preferred_output, tmds_reg);
157 /* These functions now write into the output, instead of a specific ramdac */
159 void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val)
161 NVOutputPrivatePtr nv_output = output->driver_private;
162 ScrnInfoPtr pScrn = output->scrn;
163 NVPtr pNv = NVPTR(pScrn);
165 nvWriteRAMDAC(pNv, nv_output->preferred_output, ramdac_reg, val);
168 CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg)
170 NVOutputPrivatePtr nv_output = output->driver_private;
171 ScrnInfoPtr pScrn = output->scrn;
172 NVPtr pNv = NVPTR(pScrn);
174 return nvReadRAMDAC(pNv, nv_output->preferred_output, ramdac_reg);
177 static void dpms_update_output_ramdac(xf86OutputPtr output, int mode)
179 NVOutputPrivatePtr nv_output = output->driver_private;
180 ScrnInfoPtr pScrn = output->scrn;
181 NVPtr pNv = NVPTR(pScrn);
182 xf86CrtcPtr crtc = output->crtc;
183 if (!crtc) /* we need nv_crtc, so give up */
185 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
187 /* We may be going for modesetting, so we must reset our output binding */
188 if (mode == DPMSModeOff) {
189 NVWriteVGACR5758(pNv, nv_crtc->head, 0, 0x7f);
190 NVWriteVGACR5758(pNv, nv_crtc->head, 2, 0);
194 /* The previous call was not a modeset, but a normal dpms call */
195 NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
196 NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
200 nv_lvds_output_dpms(xf86OutputPtr output, int mode)
202 NVOutputPrivatePtr nv_output = output->driver_private;
203 NVPtr pNv = NVPTR(output->scrn);
204 xf86CrtcPtr crtc = output->crtc;
205 if (!crtc) /* we need nv_crtc, so give up */
207 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
209 ErrorF("nv_lvds_output_dpms is called with mode %d\n", mode);
211 dpms_update_output_ramdac(output, mode);
213 if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_power_scripts)
217 case DPMSModeStandby:
218 case DPMSModeSuspend:
219 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_BACKLIGHT_OFF, 0);
222 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_OFF, 0);
225 call_lvds_script(output->scrn, nv_crtc->head, nv_output->dcb_entry, LVDS_PANEL_ON, 0);
232 nv_analog_output_dpms(xf86OutputPtr output, int mode)
234 xf86CrtcPtr crtc = output->crtc;
236 ErrorF("nv_analog_output_dpms is called with mode %d\n", mode);
238 dpms_update_output_ramdac(output, mode);
241 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
243 ErrorF("nv_analog_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
248 nv_tmds_output_dpms(xf86OutputPtr output, int mode)
250 xf86CrtcPtr crtc = output->crtc;
251 NVPtr pNv = NVPTR(output->scrn);
253 ErrorF("nv_tmds_output_dpms is called with mode %d\n", mode);
255 dpms_update_output_ramdac(output, mode);
257 /* Are we assigned a ramdac already?, else we will be activated during mode set */
259 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
261 ErrorF("nv_tmds_output_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
263 CARD32 fpcontrol = nvReadRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL);
265 case DPMSModeStandby:
266 case DPMSModeSuspend:
268 /* cut the TMDS output */
269 fpcontrol |= 0x20000022;
272 /* disable cutting the TMDS output */
273 fpcontrol &= ~0x20000022;
276 nvWriteRAMDAC(pNv, nv_crtc->head, NV_RAMDAC_FP_CONTROL, fpcontrol);
280 void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state)
282 NVOutputPrivatePtr nv_output = output->driver_private;
286 regp = &state->dac_reg[nv_output->preferred_output];
288 regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT);
290 /* Store the registers in case we need them again for something (like data for VT restore) */
291 for (i = 0; i < 0xFF; i++) {
292 regp->TMDS[i] = NVOutputReadTMDS(output, i);
295 for (i = 0; i < 0xFF; i++) {
296 regp->TMDS2[i] = NVOutputReadTMDS2(output, i);
300 void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state, Bool override)
302 NVOutputPrivatePtr nv_output = output->driver_private;
305 regp = &state->dac_reg[nv_output->preferred_output];
307 /* This exists purely for proper text mode restore */
308 if (override) NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output);
311 /* NOTE: Don't rely on this data for anything other than restoring VT's */
314 nv_output_save (xf86OutputPtr output)
316 ScrnInfoPtr pScrn = output->scrn;
317 NVPtr pNv = NVPTR(pScrn);
318 RIVA_HW_STATE *state;
320 ErrorF("nv_output_save is called\n");
321 state = &pNv->SavedReg;
323 /* Due to strange mapping of outputs we could have swapped analog and digital */
324 /* So we force save all the registers */
325 nv_output_save_state_ext(output, state);
328 uint32_t nv_calc_tmds_clock_from_pll(xf86OutputPtr output)
330 ScrnInfoPtr pScrn = output->scrn;
331 NVPtr pNv = NVPTR(pScrn);
332 RIVA_HW_STATE *state;
334 NVOutputPrivatePtr nv_output = output->driver_private;
336 state = &pNv->SavedReg;
337 /* Registers are stored by their preferred ramdac */
338 regp = &state->dac_reg[nv_output->preferred_output];
340 /* Only do it once for a dvi-d/dvi-a pair */
341 Bool swapped_clock = FALSE;
342 Bool vpllb_disabled = FALSE;
343 /* Bit3 swaps crtc (clocks are bound to crtc) and output */
344 if (regp->TMDS[0x4] & (1 << 3)) {
345 swapped_clock = TRUE;
348 uint8_t vpll_num = swapped_clock ^ nv_output->preferred_output;
353 /* For the moment the syntax is the same for NV40 and earlier */
354 if (pNv->Architecture == NV_ARCH_40) {
355 vplla = vpll_num ? state->vpll2_a : state->vpll1_a;
356 vpllb = vpll_num ? state->vpll2_b : state->vpll1_b;
358 vplla = vpll_num ? state->vpll2 : state->vpll;
359 if (pNv->twoStagePLL)
360 vpllb = vpll_num ? state->vpll2B : state->vpllB;
363 if (!pNv->twoStagePLL)
364 vpllb_disabled = TRUE;
366 /* This is the dummy value nvidia sets when vpll is disabled */
367 if ((vpllb & 0xFFFF) == 0x11F)
368 vpllb_disabled = TRUE;
370 uint8_t m1, m2, n1, n2, p;
373 n1 = (vplla >> 8) & 0xFF;
374 p = (vplla >> 16) & 0x7;
376 if (vpllb_disabled) {
381 n2 = (vpllb >> 8) & 0xFF;
384 uint32_t clock = ((pNv->CrystalFreqKHz * n1 * n2)/(m1 * m2)) >> p;
385 ErrorF("The original bios clock seems to have been %d kHz\n", clock);
389 void nv_set_tmds_registers(xf86OutputPtr output, uint32_t clock, Bool override, Bool crosswired)
391 ScrnInfoPtr pScrn = output->scrn;
392 NVOutputPrivatePtr nv_output = output->driver_private;
393 xf86CrtcPtr crtc = output->crtc;
394 /* We have no crtc, so what are we supposed to do now? */
395 /* This can only happen during VT restore */
396 if (crtc && !override) {
397 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
399 * Resetting all registers is a bad idea, it seems to work fine without it.
401 if (nv_output->type == OUTPUT_TMDS)
402 run_tmds_table(pScrn, nv_output->dcb_entry, nv_crtc->head, clock/10);
404 call_lvds_script(pScrn, nv_crtc->head, nv_output->dcb_entry, LVDS_RESET, clock / 10);
407 * We have no crtc, but we do know what output we are and if we were crosswired.
408 * We can determine our crtc from this.
410 if (nv_output->type == OUTPUT_TMDS)
411 run_tmds_table(pScrn, nv_output->dcb_entry, nv_output->preferred_output ^ crosswired, clock/10);
413 call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_RESET, clock / 10);
414 call_lvds_script(pScrn, nv_output->preferred_output ^ crosswired, nv_output->dcb_entry, LVDS_PANEL_ON, 0);
420 nv_output_restore (xf86OutputPtr output)
422 ScrnInfoPtr pScrn = output->scrn;
423 NVPtr pNv = NVPTR(pScrn);
424 RIVA_HW_STATE *state;
425 NVOutputPrivatePtr nv_output = output->driver_private;
427 ErrorF("nv_output_restore is called\n");
429 state = &pNv->SavedReg;
430 regp = &state->dac_reg[nv_output->preferred_output];
432 /* Due to strange mapping of outputs we could have swapped analog and digital */
433 /* So we force load all the registers */
434 nv_output_load_state_ext(output, state, TRUE);
438 nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
440 if (pMode->Flags & V_DBLSCAN)
441 return MODE_NO_DBLESCAN;
443 if (pMode->Clock > 400000 || pMode->Clock < 25000)
444 return MODE_CLOCK_RANGE;
451 nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
452 DisplayModePtr adjusted_mode)
454 ErrorF("nv_output_mode_fixup is called\n");
460 nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
462 NVOutputPrivatePtr nv_output = output->driver_private;
463 ScrnInfoPtr pScrn = output->scrn;
464 //RIVA_HW_STATE *state;
465 //NVOutputRegPtr regp, savep;
467 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
470 /* It's getting quiet here, not removing function just yet, we may still need it */
472 //state = &pNv->ModeReg;
473 //regp = &state->dac_reg[nv_output->preferred_output];
475 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
479 NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private;
483 for (i = 0; i < config->num_output; i++) {
484 NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private;
486 /* is it this output ?? */
487 if (config->output[i] == output)
490 /* it the output connected */
491 if (config->output[i]->crtc == NULL)
495 if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) {
500 ErrorF("%d: crtc %d output %d twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->preferred_output, two_crt, two_mon);
505 nv_have_duallink(ScrnInfoPtr pScrn)
507 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
508 NVPtr pNv = NVPTR(pScrn);
511 for (i = 0; i < xf86_config->num_output; i++) {
512 xf86OutputPtr output = xf86_config->output[i];
513 NVOutputPrivatePtr nv_output = output->driver_private;
514 if (pNv->dcb_table.entry[nv_output->dcb_entry].duallink_possible)
522 nv_output_mode_set_routing(xf86OutputPtr output)
524 NVOutputPrivatePtr nv_output = output->driver_private;
525 xf86CrtcPtr crtc = output->crtc;
526 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
527 ScrnInfoPtr pScrn = output->scrn;
528 NVPtr pNv = NVPTR(pScrn);
531 uint32_t output_reg[2] = {0, 0};
533 if ((nv_output->type == OUTPUT_LVDS) || (nv_output->type == OUTPUT_TMDS)) {
537 if (pNv->Architecture == NV_ARCH_40) {
538 /* NV4x cards have strange ways of dealing with dualhead */
539 /* Also see reg594 in nv_crtc.c */
540 output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
541 /* This seems to be restricted to dual link outputs. */
542 /* Some cards have secondary outputs with ffs(or) != 3. */
543 if (nv_have_duallink(pScrn) || pNv->restricted_mode)
544 output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
546 /* This is for simplicity */
547 output_reg[0] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
548 output_reg[1] = NV_RAMDAC_OUTPUT_DAC_ENABLE;
551 /* Some pre-NV30 cards have switchable crtc's. */
552 if (pNv->switchable_crtc) {
553 if (pNv->restricted_mode) { /* some NV4A for example */
554 if (nv_output->preferred_output != nv_crtc->head) {
555 output_reg[0] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
557 output_reg[1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
560 output_reg[1] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
561 /* Does this have something to do with outputs that have ffs(or) == 1? */
562 /* I suspect this bit represents more than just a crtc switch. */
563 if (nv_crtc->head != nv_output->preferred_output) {
564 output_reg[0] |= NV_RAMDAC_OUTPUT_SELECT_CRTC1;
569 /* The registers can't be considered seperately on most cards */
570 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_OUTPUT, output_reg[0]);
571 nvWriteRAMDAC(pNv, 1, NV_RAMDAC_OUTPUT, output_reg[1]);
573 /* This could use refinement for flatpanels, but it should work this way */
574 if (pNv->NVArch < 0x44) {
575 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, 0xf0000000);
576 if (pNv->Architecture == NV_ARCH_40)
577 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0xf0000000);
579 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, 0x00100000);
580 nvWriteRAMDAC(pNv, 0, NV_RAMDAC_670, 0x00100000);
585 nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
586 DisplayModePtr adjusted_mode)
588 ScrnInfoPtr pScrn = output->scrn;
589 NVPtr pNv = NVPTR(pScrn);
590 NVOutputPrivatePtr nv_output = output->driver_private;
591 RIVA_HW_STATE *state;
593 ErrorF("nv_output_mode_set is called\n");
595 state = &pNv->ModeReg;
597 nv_output_mode_set_regs(output, mode, adjusted_mode);
598 nv_output_load_state_ext(output, state, FALSE);
599 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS)
600 nv_set_tmds_registers(output, adjusted_mode->Clock, FALSE, FALSE);
602 nv_output_mode_set_routing(output);
606 nv_get_edid(xf86OutputPtr output)
608 /* no use for shared DDC output */
609 NVOutputPrivatePtr nv_output = output->driver_private;
612 if (nv_output->pDDCBus == NULL)
615 ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
619 if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG))
622 if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_TMDS ||
623 nv_output->type == OUTPUT_LVDS))
634 nv_ddc_detect(xf86OutputPtr output)
636 xf86MonPtr m = nv_get_edid(output);
646 nv_crt_load_detect(xf86OutputPtr output)
648 ScrnInfoPtr pScrn = output->scrn;
649 NVOutputPrivatePtr nv_output = output->driver_private;
650 NVPtr pNv = NVPTR(pScrn);
651 CARD32 reg_output, reg_test_ctrl, temp;
652 Bool present = FALSE;
654 /* For some reason we get false positives on output 1, maybe due tv-out? */
655 if (nv_output->preferred_output == 1) {
659 if (nv_output->pDDCBus != NULL) {
660 xf86MonPtr ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus);
661 /* Is there a digital flatpanel on this channel? */
662 if (ddc_mon && ddc_mon->features.input_type) {
667 reg_output = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT);
668 reg_test_ctrl = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL);
670 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000));
672 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE));
675 temp = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT);
676 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, temp | 1);
678 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_DATA, 0x94050140);
679 temp = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL);
680 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000);
684 present = (nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE;
686 temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL);
687 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF);
689 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_OUTPUT, reg_output);
690 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl);
693 ErrorF("A crt was detected on output %d with no ddc support\n", nv_output->preferred_output);
700 static xf86OutputStatus
701 nv_tmds_output_detect(xf86OutputPtr output)
703 ErrorF("nv_tmds_output_detect is called\n");
705 if (nv_ddc_detect(output))
706 return XF86OutputStatusConnected;
708 return XF86OutputStatusDisconnected;
712 static xf86OutputStatus
713 nv_analog_output_detect(xf86OutputPtr output)
715 ErrorF("nv_analog_output_detect is called\n");
717 if (nv_ddc_detect(output))
718 return XF86OutputStatusConnected;
720 if (nv_crt_load_detect(output))
721 return XF86OutputStatusConnected;
723 return XF86OutputStatusDisconnected;
726 static DisplayModePtr
727 nv_output_get_modes(xf86OutputPtr output)
729 NVOutputPrivatePtr nv_output = output->driver_private;
731 DisplayModePtr ddc_modes;
733 ErrorF("nv_output_get_modes is called\n");
735 ddc_mon = nv_get_edid(output);
737 xf86OutputSetEDID(output, ddc_mon);
742 ddc_modes = xf86OutputGetEDIDModes (output);
744 if (nv_output->type == OUTPUT_TMDS || nv_output->type == OUTPUT_LVDS) {
748 for (i = 0; i < 4; i++) {
749 /* We only look at detailed timings atm */
750 if (ddc_mon->det_mon[i].type != DT)
752 /* Selecting only based on width ok? */
753 if (ddc_mon->det_mon[i].section.d_timings.h_active > nv_output->fpWidth) {
754 nv_output->fpWidth = ddc_mon->det_mon[i].section.d_timings.h_active;
755 nv_output->fpHeight = ddc_mon->det_mon[i].section.d_timings.v_active;
759 /* Add a native resolution mode that is preferred */
760 /* Reduced blanking should be fine on DVI monitor */
761 nv_output->native_mode = xf86CVTMode(nv_output->fpWidth, nv_output->fpHeight, 60.0, TRUE, FALSE);
762 nv_output->native_mode->type = M_T_DRIVER | M_T_PREFERRED;
764 if (output->funcs->mode_valid(output, nv_output->native_mode) == MODE_OK) {
765 /* We want the new mode to be preferred */
766 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
767 if (mode->type & M_T_PREFERRED) {
768 mode->type &= ~M_T_PREFERRED;
771 ddc_modes = xf86ModesAdd(ddc_modes, nv_output->native_mode);
772 } else { /* invalid mode */
773 nv_output->native_mode = NULL;
774 for (mode = ddc_modes; mode != NULL; mode = mode->next) {
775 if (mode->HDisplay == nv_output->fpWidth &&
776 mode->VDisplay == nv_output->fpHeight) {
778 nv_output->native_mode = mode;
782 if (!nv_output->native_mode) {
783 ErrorF("Really bad stuff happening, CVT mode bad and no other native mode can be found.\n");
784 ErrorF("Bailing out\n");
787 ErrorF("CVT mode was invalid(=bad), but another mode was found\n");
796 nv_output_destroy (xf86OutputPtr output)
798 ErrorF("nv_output_destroy is called\n");
799 if (output->driver_private)
800 xfree (output->driver_private);
804 nv_output_prepare(xf86OutputPtr output)
806 ErrorF("nv_output_prepare is called\n");
807 NVOutputPrivatePtr nv_output = output->driver_private;
808 ScrnInfoPtr pScrn = output->scrn;
809 xf86CrtcPtr crtc = output->crtc;
810 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
811 NVPtr pNv = NVPTR(pScrn);
813 output->funcs->dpms(output, DPMSModeOff);
815 /* Shut down the tmds pll, a short sleep period will happen at crtc prepare. */
816 uint32_t debug0 = nvReadRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_FP_DEBUG_0) |
817 NV_RAMDAC_FP_DEBUG_0_PWRDOWN_TMDS_PLL;
818 nvWriteRAMDAC(pNv, nv_output->preferred_output, NV_RAMDAC_FP_DEBUG_0, debug0);
820 /* Set our output type and output routing possibilities to the right registers */
821 NVWriteVGACR5758(pNv, nv_crtc->head, 0, pNv->dcb_table.entry[nv_output->dcb_entry].type);
822 NVWriteVGACR5758(pNv, nv_crtc->head, 2, pNv->dcb_table.entry[nv_output->dcb_entry].or);
826 nv_output_commit(xf86OutputPtr output)
828 ErrorF("nv_output_commit is called\n");
830 output->funcs->dpms(output, DPMSModeOn);
833 static const xf86OutputFuncsRec nv_analog_output_funcs = {
834 .dpms = nv_analog_output_dpms,
835 .save = nv_output_save,
836 .restore = nv_output_restore,
837 .mode_valid = nv_output_mode_valid,
838 .mode_fixup = nv_output_mode_fixup,
839 .mode_set = nv_output_mode_set,
840 .detect = nv_analog_output_detect,
841 .get_modes = nv_output_get_modes,
842 .destroy = nv_output_destroy,
843 .prepare = nv_output_prepare,
844 .commit = nv_output_commit,
847 #ifdef RANDR_12_INTERFACE
849 * Several scaling modes exist, let the user choose.
851 #define SCALING_MODE_NAME "SCALING_MODE"
852 static const struct {
854 enum scaling_modes mode;
856 { "panel", SCALE_PANEL },
857 { "fullscreen", SCALE_FULLSCREEN },
858 { "aspect", SCALE_ASPECT },
859 { "noscale", SCALE_NOSCALE },
860 { NULL, SCALE_INVALID}
862 static Atom scaling_mode_atom;
865 nv_scaling_mode_lookup(char *name, int size)
869 /* for when name is zero terminated */
873 for (i = 0; scaling_mode[i].name; i++)
874 /* We're getting non-terminated strings */
875 if (strlen(scaling_mode[i].name) >= size &&
876 !strncasecmp(name, scaling_mode[i].name, size))
879 return scaling_mode[i].mode;
883 nv_digital_output_create_resources(xf86OutputPtr output)
885 NVOutputPrivatePtr nv_output = output->driver_private;
886 ScrnInfoPtr pScrn = output->scrn;
890 * Setup scaling mode property.
892 scaling_mode_atom = MakeAtom(SCALING_MODE_NAME, sizeof(SCALING_MODE_NAME) - 1, TRUE);
894 error = RRConfigureOutputProperty(output->randr_output,
895 scaling_mode_atom, TRUE, FALSE, FALSE,
899 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
900 "RRConfigureOutputProperty error, %d\n", error);
903 char *existing_scale_name = NULL;
904 for (i = 0; scaling_mode[i].name; i++)
905 if (scaling_mode[i].mode == nv_output->scaling_mode)
906 existing_scale_name = scaling_mode[i].name;
908 error = RRChangeOutputProperty(output->randr_output, scaling_mode_atom,
909 XA_STRING, 8, PropModeReplace,
910 strlen(existing_scale_name),
911 existing_scale_name, FALSE, TRUE);
914 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
915 "Failed to set scaling mode, %d\n", error);
920 nv_digital_output_set_property(xf86OutputPtr output, Atom property,
921 RRPropertyValuePtr value)
923 NVOutputPrivatePtr nv_output = output->driver_private;
925 if (property == scaling_mode_atom) {
929 if (value->type != XA_STRING || value->format != 8)
932 name = (char *) value->data;
934 /* Match a string to a scaling mode */
935 ret = nv_scaling_mode_lookup(name, value->size);
936 if (ret == SCALE_INVALID)
939 nv_output->scaling_mode = ret;
946 #endif /* RANDR_12_INTERFACE */
949 nv_tmds_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
951 NVOutputPrivatePtr nv_output = output->driver_private;
953 /* We can't exceed the native mode.*/
954 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
957 return nv_output_mode_valid(output, pMode);
960 static const xf86OutputFuncsRec nv_tmds_output_funcs = {
961 .dpms = nv_tmds_output_dpms,
962 .save = nv_output_save,
963 .restore = nv_output_restore,
964 .mode_valid = nv_tmds_output_mode_valid,
965 .mode_fixup = nv_output_mode_fixup,
966 .mode_set = nv_output_mode_set,
967 .detect = nv_tmds_output_detect,
968 .get_modes = nv_output_get_modes,
969 .destroy = nv_output_destroy,
970 .prepare = nv_output_prepare,
971 .commit = nv_output_commit,
972 #ifdef RANDR_12_INTERFACE
973 .create_resources = nv_digital_output_create_resources,
974 .set_property = nv_digital_output_set_property,
975 #endif /* RANDR_12_INTERFACE */
978 static int nv_lvds_output_mode_valid
979 (xf86OutputPtr output, DisplayModePtr pMode)
981 NVOutputPrivatePtr nv_output = output->driver_private;
983 /* No modes > panel's native res */
984 if (pMode->HDisplay > nv_output->fpWidth || pMode->VDisplay > nv_output->fpHeight)
987 return nv_output_mode_valid(output, pMode);
990 static xf86OutputStatus
991 nv_lvds_output_detect(xf86OutputPtr output)
993 ScrnInfoPtr pScrn = output->scrn;
994 NVPtr pNv = NVPTR(pScrn);
995 NVOutputPrivatePtr nv_output = output->driver_private;
997 if (pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode &&
998 pNv->VBIOS.fp.native_mode)
999 return XF86OutputStatusConnected;
1000 if (nv_ddc_detect(output))
1001 return XF86OutputStatusConnected;
1003 return XF86OutputStatusDisconnected;
1006 static DisplayModePtr
1007 nv_lvds_output_get_modes(xf86OutputPtr output)
1009 ScrnInfoPtr pScrn = output->scrn;
1010 NVPtr pNv = NVPTR(pScrn);
1011 NVOutputPrivatePtr nv_output = output->driver_private;
1012 DisplayModePtr modes;
1014 if ((modes = nv_output_get_modes(output)))
1017 /* it is possible to set up a mode from what we can read from the
1018 * RAMDAC registers, but if we can't read the BIOS table correctly
1019 * we might as well give up */
1020 if (!pNv->dcb_table.entry[nv_output->dcb_entry].lvdsconf.use_straps_for_mode ||
1021 (pNv->VBIOS.fp.native_mode == NULL))
1024 nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1;
1025 nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1;
1026 nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033;
1028 if (pNv->VBIOS.fp.native_mode->HDisplay != nv_output->fpWidth ||
1029 pNv->VBIOS.fp.native_mode->VDisplay != nv_output->fpHeight) {
1030 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1031 "Panel size mismatch; ignoring RAMDAC\n");
1032 nv_output->fpWidth = pNv->VBIOS.fp.native_mode->HDisplay;
1033 nv_output->fpHeight = pNv->VBIOS.fp.native_mode->VDisplay;
1036 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %u x %u\n",
1037 nv_output->fpWidth, nv_output->fpHeight);
1039 nv_output->native_mode = xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1041 return xf86DuplicateMode(pNv->VBIOS.fp.native_mode);
1044 static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1045 .dpms = nv_lvds_output_dpms,
1046 .save = nv_output_save,
1047 .restore = nv_output_restore,
1048 .mode_valid = nv_lvds_output_mode_valid,
1049 .mode_fixup = nv_output_mode_fixup,
1050 .mode_set = nv_output_mode_set,
1051 .detect = nv_lvds_output_detect,
1052 .get_modes = nv_lvds_output_get_modes,
1053 .destroy = nv_output_destroy,
1054 .prepare = nv_output_prepare,
1055 .commit = nv_output_commit,
1056 #ifdef RANDR_12_INTERFACE
1057 .create_resources = nv_digital_output_create_resources,
1058 .set_property = nv_digital_output_set_property,
1059 #endif /* RANDR_12_INTERFACE */
1062 static void nv_add_analog_output(ScrnInfoPtr pScrn, int dcb_entry, Bool dvi_pair)
1064 NVPtr pNv = NVPTR(pScrn);
1065 xf86OutputPtr output;
1066 NVOutputPrivatePtr nv_output;
1067 char outputname[20];
1068 Bool create_output = TRUE;
1069 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1071 /* DVI have an analog connector and a digital one, differentiate between that and a normal vga */
1073 sprintf(outputname, "DVI-A-%d", pNv->dvi_a_count);
1076 sprintf(outputname, "VGA-%d", pNv->vga_count);
1080 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1085 nv_output->dcb_entry = dcb_entry;
1087 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1088 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1090 nv_output->type = OUTPUT_ANALOG;
1093 * bit0: OUTPUT_0 valid
1094 * bit1: OUTPUT_1 valid
1095 * So lowest order has highest priority.
1096 * Below is guesswork:
1097 * bit2: All outputs valid
1099 /* This also facilitates proper output routing for dvi */
1100 /* See sel_clk assignment in nv_crtc.c */
1101 if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1) {
1102 nv_output->preferred_output = 1;
1104 nv_output->preferred_output = 0;
1107 nv_output->bus = pNv->dcb_table.entry[dcb_entry].bus;
1109 if (!create_output) {
1114 /* Delay creation of output until we actually know we want it */
1115 output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname);
1119 output->driver_private = nv_output;
1121 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1123 if (pNv->switchable_crtc) {
1124 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1126 output->possible_crtcs = (1 << nv_output->preferred_output);
1129 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1132 static void nv_add_digital_output(ScrnInfoPtr pScrn, int dcb_entry, int lvds)
1134 NVPtr pNv = NVPTR(pScrn);
1135 xf86OutputPtr output;
1136 NVOutputPrivatePtr nv_output;
1137 char outputname[20];
1138 Bool create_output = TRUE;
1139 int i2c_index = pNv->dcb_table.entry[dcb_entry].i2c_index;
1142 sprintf(outputname, "LVDS-%d", pNv->lvds_count);
1145 sprintf(outputname, "DVI-D-%d", pNv->dvi_d_count);
1149 nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1);
1155 nv_output->dcb_entry = dcb_entry;
1157 if (pNv->dcb_table.i2c_read[i2c_index] && pNv->pI2CBus[i2c_index] == NULL)
1158 NV_I2CInit(pScrn, &pNv->pI2CBus[i2c_index], pNv->dcb_table.i2c_read[i2c_index], xstrdup(outputname));
1160 nv_output->pDDCBus = pNv->pI2CBus[i2c_index];
1163 * bit0: OUTPUT_0 valid
1164 * bit1: OUTPUT_1 valid
1165 * So lowest order has highest priority.
1166 * Below is guesswork:
1167 * bit2: All outputs valid
1169 /* This also facilitates proper output routing for dvi */
1170 /* See sel_clk assignment in nv_crtc.c */
1171 if (ffs(pNv->dcb_table.entry[dcb_entry].or) & OUTPUT_1) {
1172 nv_output->preferred_output = 1;
1174 nv_output->preferred_output = 0;
1177 nv_output->bus = pNv->dcb_table.entry[dcb_entry].bus;
1180 nv_output->type = OUTPUT_LVDS;
1181 /* comment below two lines to test LVDS under RandR12.
1182 * If your screen "blooms" or "bleeds" (i.e. has a developing
1183 * white / psychedelic pattern) then KILL X IMMEDIATELY
1184 * (ctrl+alt+backspace) & if the effect continues reset power */
1185 ErrorF("Output refused because we don't accept LVDS at the moment.\n");
1186 create_output = FALSE;
1188 nv_output->type = OUTPUT_TMDS;
1191 if (!create_output) {
1196 /* Delay creation of output until we are certain is desirable */
1198 output = xf86OutputCreate (pScrn, &nv_lvds_output_funcs, outputname);
1200 output = xf86OutputCreate (pScrn, &nv_tmds_output_funcs, outputname);
1204 output->driver_private = nv_output;
1206 if (pNv->fpScaler) /* GPU Scaling */
1207 nv_output->scaling_mode = SCALE_ASPECT;
1208 else /* Panel scaling */
1209 nv_output->scaling_mode = SCALE_PANEL;
1211 #ifdef RANDR_12_INTERFACE
1212 if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
1213 nv_output->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
1214 if (nv_output->scaling_mode == SCALE_INVALID)
1215 nv_output->scaling_mode = SCALE_ASPECT; /* default */
1217 #endif /* RANDR_12_INTERFACE */
1219 /* Due to serious problems we have to restrict the crtc's for certain types of outputs. */
1220 /* This is a result of problems with G70 cards that have a dvi with ffs(or) == 1 */
1221 /* Anyone know what the solution for this is? */
1222 if (nv_output->preferred_output == 0) {
1223 output->possible_crtcs = (1 << 0);
1225 if (pNv->switchable_crtc) {
1226 output->possible_crtcs = pNv->dcb_table.entry[dcb_entry].heads;
1228 output->possible_crtcs = (1 << nv_output->preferred_output);
1232 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname);
1235 void NvDCBSetupOutputs(ScrnInfoPtr pScrn)
1237 NVPtr pNv = NVPTR(pScrn);
1238 int i, type, i2c_count[0xf];
1240 pNv->switchable_crtc = FALSE;
1241 /* I was wrong, again. */
1242 if (pNv->NVArch > 0x11 && pNv->twoHeads)
1243 pNv->switchable_crtc = TRUE;
1245 memset(i2c_count, 0, sizeof(i2c_count));
1246 for (i = 0 ; i < pNv->dcb_table.entries; i++)
1247 i2c_count[pNv->dcb_table.entry[i].i2c_index]++;
1249 /* we setup the outputs up from the BIOS table */
1250 for (i = 0 ; i < pNv->dcb_table.entries; i++) {
1251 type = pNv->dcb_table.entry[i].type;
1253 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DCB type %d not known\n", type);
1257 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);
1261 nv_add_analog_output(pScrn, i, (i2c_count[pNv->dcb_table.entry[i].i2c_index] > 1));
1264 nv_add_digital_output(pScrn, i, 0);
1267 nv_add_digital_output(pScrn, i, 1);
1275 void NvSetupOutputs(ScrnInfoPtr pScrn)
1277 NVPtr pNv = NVPTR(pScrn);
1279 pNv->Television = FALSE;
1281 memset(pNv->pI2CBus, 0, sizeof(pNv->pI2CBus));
1282 NvDCBSetupOutputs(pScrn);
1285 /*************************************************************************** \
1287 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1289 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1290 |* international laws. Users and possessors of this source code are *|
1291 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1292 |* use this code in individual and commercial software. *|
1294 |* Any use of this source code must include, in the user documenta- *|
1295 |* tion and internal comments to the code, notices to the end user *|
1298 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1300 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1301 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1302 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1303 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1304 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1305 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1306 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1307 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1308 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1309 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1310 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1312 |* U.S. Government End Users. This source code is a "commercial *|
1313 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1314 |* consisting of "commercial computer software" and "commercial *|
1315 |* computer software documentation," as such terms are used in *|
1316 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1317 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1318 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1319 |* all U.S. Government End Users acquire the source code with only *|
1320 |* those rights set forth herein. *|
1322 \***************************************************************************/