summaryrefslogtreecommitdiff
path: root/src/nv_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_output.c')
-rw-r--r--src/nv_output.c1293
1 files changed, 0 insertions, 1293 deletions
diff --git a/src/nv_output.c b/src/nv_output.c
deleted file mode 100644
index 2573702..0000000
--- a/src/nv_output.c
+++ /dev/null
@@ -1,1293 +0,0 @@
1/*
2 * Copyright 2003 NVIDIA, Corporation
3 * Copyright 2006 Dave Airlie
4 * Copyright 2007 Maarten Maathuis
5 * Copyright 2007-2009 Stuart Bennett
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#include <X11/Xatom.h>
28#include <X11/Xos.h> /* X_GETTIMEOFDAY */
29#include "nv_include.h"
30
31#define MULTIPLE_ENCODERS(e) (e & (e - 1))
32#define FOR_EACH_ENCODER_IN_CONNECTOR(i, c, e) for (i = 0; i < pNv->vbios->dcb->entries; i++) \
33 if (c->possible_encoders & (1 << i) && \
34 (e = &pNv->encoders[i]))
35
36static int nv_output_ramdac_offset(struct nouveau_encoder *nv_encoder)
37{
38 int offset = 0;
39
40 if (nv_encoder->dcb->or & (8 | OUTPUT_C))
41 offset += 0x68;
42 if (nv_encoder->dcb->or & (8 | OUTPUT_B))
43 offset += 0x2000;
44
45 return offset;
46}
47
48static int nv_get_digital_bound_head(NVPtr pNv, int or)
49{
50 /* special case of nv_read_tmds to find crtc associated with an output.
51 * this does not give a correct answer for off-chip dvi, but there's no
52 * use for such an answer anyway
53 */
54 int ramdac = (or & OUTPUT_C) >> 2;
55
56 NVWriteRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL,
57 NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
58 return (((NVReadRAMDAC(pNv, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac);
59}
60
61#define WAIT_FOR(cond, timeout_us) __extension__ ({ \
62 struct timeval begin, cur; \
63 long d_secs, d_usecs, diff = 0; \
64 \
65 X_GETTIMEOFDAY(&begin); \
66 while (!(cond) && diff < timeout_us) { \
67 X_GETTIMEOFDAY(&cur); \
68 d_secs = cur.tv_sec - begin.tv_sec; \
69 d_usecs = cur.tv_usec - begin.tv_usec; \
70 diff = d_secs * 1000000 + d_usecs; \
71 }; \
72 diff >= timeout_us ? -EAGAIN : 0; \
73})
74
75/*
76 * arbitrary limit to number of sense oscillations tolerated in one sample
77 * period (observed to be at least 13 in "nvidia")
78 */
79#define MAX_HBLANK_OSC 20
80
81/*
82 * arbitrary limit to number of conflicting sample pairs to tolerate at a
83 * voltage step (observed to be at least 5 in "nvidia")
84 */
85#define MAX_SAMPLE_PAIRS 10
86
87static int sample_load_twice(NVPtr pNv, bool sense[2])
88{
89 int i;
90
91 for (i = 0; i < 2; i++) {
92 bool sense_a, sense_b, sense_b_prime;
93 int j = 0;
94
95 /*
96 * wait for bit 0 clear -- out of hblank -- (say reg value 0x4),
97 * then wait for transition 0x4->0x5->0x4: enter hblank, leave
98 * hblank again
99 * use a 10ms timeout (guards against crtc being inactive, in
100 * which case blank state would never change)
101 */
102 if (WAIT_FOR(!(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1), 10000))
103 return -EWOULDBLOCK;
104 if (WAIT_FOR(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1, 10000))
105 return -EWOULDBLOCK;
106 if (WAIT_FOR(!(VGA_RD08(pNv->REGS, NV_PRMCIO_INP0__COLOR) & 1), 10000))
107 return -EWOULDBLOCK;
108
109 WAIT_FOR(0, 100); /* faster than usleep(100) */
110 /* when level triggers, sense is _LO_ */
111 sense_a = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
112
113 /* take another reading until it agrees with sense_a... */
114 do {
115 WAIT_FOR(0, 100);
116 sense_b = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
117 if (sense_a != sense_b) {
118 sense_b_prime = VGA_RD08(pNv->REGS, NV_PRMCIO_INP0) & 0x10;
119 if (sense_b == sense_b_prime) {
120 /* ... unless two consecutive subsequent
121 * samples agree; sense_a is replaced */
122 sense_a = sense_b;
123 /* force mis-match so we loop */
124 sense_b = !sense_a;
125 }
126 }
127 } while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC);
128
129 if (j == MAX_HBLANK_OSC)
130 /* with so much oscillation, default to sense:LO */
131 sense[i] = false;
132 else
133 sense[i] = sense_a;
134 }
135
136 return 0;
137}
138
139static bool nv_legacy_load_detect(ScrnInfoPtr pScrn)
140{
141 NVPtr pNv = NVPTR(pScrn);
142 uint8_t saved_seq1, saved_pi, saved_rpc1;
143 uint8_t saved_palette0[3], saved_palette_mask;
144 uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
145 int i;
146 uint8_t blue;
147 bool sense = true;
148
149 /*
150 * for this detection to work, there needs to be a mode set up on the
151 * CRTC. this is presumed to be the case
152 */
153
154 if (pNv->twoHeads)
155 /* only implemented for head A for now */
156 NVSetOwner(pNv, 0);
157
158 saved_seq1 = NVReadVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX);
159 NVWriteVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
160
161 saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL);
162 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL,
163 saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
164
165 usleep(10000);
166
167 saved_pi = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX);
168 NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX,
169 saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT)));
170 saved_rpc1 = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX);
171 NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0);
172
173 VGA_WR08(pNv->REGS, NV_PRMDIO_READ_MODE_ADDRESS, 0x0);
174 for (i = 0; i < 3; i++)
175 saved_palette0[i] = NV_RD08(pNv->REGS, NV_PRMDIO_PALETTE_DATA);
176 saved_palette_mask = NV_RD08(pNv->REGS, NV_PRMDIO_PIXEL_MASK);
177 VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK, 0);
178
179 saved_rgen_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL);
180 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL,
181 (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
182 NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) |
183 NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON);
184
185 blue = 8; /* start of test range */
186
187 do {
188 bool sense_pair[2];
189
190 VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
191 NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, 0);
192 NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, 0);
193 /* testing blue won't find monochrome monitors. I don't care */
194 NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, blue);
195
196 i = 0;
197 /* take sample pairs until both samples in the pair agree */
198 do {
199 if (sample_load_twice(pNv, sense_pair))
200 goto out;
201 } while ((sense_pair[0] != sense_pair[1]) &&
202 ++i < MAX_SAMPLE_PAIRS);
203
204 if (i == MAX_SAMPLE_PAIRS)
205 /* too much oscillation defaults to LO */
206 sense = false;
207 else
208 sense = sense_pair[0];
209
210 /*
211 * if sense goes LO before blue ramps to 0x18, monitor is not connected.
212 * ergo, if blue gets to 0x18, monitor must be connected
213 */
214 } while (++blue < 0x18 && sense);
215
216out:
217 VGA_WR08(pNv->REGS, NV_PRMDIO_PIXEL_MASK, saved_palette_mask);
218 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl);
219 VGA_WR08(pNv->REGS, NV_PRMDIO_WRITE_MODE_ADDRESS, 0);
220 for (i = 0; i < 3; i++)
221 NV_WR08(pNv->REGS, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]);
222 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl);
223 NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
224 NVWriteVgaCrtc(pNv, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
225 NVWriteVgaSeq(pNv, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
226
227 if (blue == 0x18) {
228 NV_TRACE(pScrn, "Load detected on head A\n");
229 return true;
230 }
231
232 return false;
233}
234
235static bool
236nv_nv17_load_detect(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
237{
238 NVPtr pNv = NVPTR(pScrn);
239 uint32_t testval, regoffset = nv_output_ramdac_offset(nv_encoder);
240 uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, saved_rtest_ctrl, temp;
241 int head, present = 0;
242 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
243
244#define RGB_TEST_DATA(r,g,b) (r << 0 | g << 10 | b << 20)
245 testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */
246 if (pNv->vbios->dactestval)
247 testval = pNv->vbios->dactestval;
248
249 saved_rtest_ctrl = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset);
250 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset,
251 saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF);
252
253 saved_powerctrl_2 = nvReadMC(pNv, NV_PBUS_POWERCTRL_2);
254
255 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff);
256 if (regoffset == 0x68) {
257 saved_powerctrl_4 = nvReadMC(pNv, NV_PBUS_POWERCTRL_4);
258 nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
259 }
260
261 usleep(4000);
262
263 saved_routput = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
264 head = (saved_routput & 0x100) >> 8;
265 /* if there's a spare crtc, using it will minimise flicker for the case
266 * where the in-use crtc is in use by an off-chip tmds encoder */
267 if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
268 head ^= 1;
269 /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
270 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset,
271 (saved_routput & 0xfffffece) | head << 8);
272 usleep(1000);
273
274 temp = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset);
275 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1);
276
277 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TESTPOINT_DATA,
278 NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval);
279 temp = NVReadRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL);
280 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL,
281 temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
282 usleep(1000);
283
284 present = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) &
285 NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI;
286
287 temp = NVReadRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL);
288 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TEST_CONTROL,
289 temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED);
290 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_TESTPOINT_DATA, 0);
291
292 /* bios does something more complex for restoring, but I think this is good enough */
293 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput);
294 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl);
295 if (regoffset == 0x68)
296 nvWriteMC(pNv, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
297 nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
298
299 if (present) {
300 NV_TRACE(pScrn, "Load detected on output %c\n",
301 '@' + ffs(nv_encoder->dcb->or));
302 return true;
303 }
304
305 return false;
306}
307
308static void
309update_output_fields(xf86OutputPtr output, struct nouveau_encoder *det_encoder)
310{
311 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
312 NVPtr pNv = NVPTR(output->scrn);
313
314 if (nv_connector->detected_encoder == det_encoder)
315 return;
316
317 nv_connector->detected_encoder = det_encoder;
318 output->possible_crtcs = det_encoder->dcb->heads;
319 if (IS_DFP(det_encoder->dcb->type)) {
320 output->doubleScanAllowed = false;
321 output->interlaceAllowed = false;
322 } else {
323 output->doubleScanAllowed = true;
324 if (pNv->Architecture == NV_ARCH_20 ||
325 (pNv->Architecture == NV_ARCH_10 &&
326 (pNv->Chipset & 0x0ff0) != CHIPSET_NV10 &&
327 (pNv->Chipset & 0x0ff0) != CHIPSET_NV15))
328 /* HW is broken */
329 output->interlaceAllowed = false;
330 else
331 output->interlaceAllowed = true;
332 }
333}
334
335static bool edid_sink_connected(xf86OutputPtr output)
336{
337 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
338 NVPtr pNv = NVPTR(output->scrn);
339 bool waslocked = NVLockVgaCrtcs(pNv, false);
340 bool wastied = nv_heads_tied(pNv);
341
342 if (wastied)
343 NVSetOwner(pNv, 0); /* necessary? */
344
345 nv_connector->edid = xf86OutputGetEDID(output, nv_connector->pDDCBus);
346
347 if (wastied)
348 NVSetOwner(pNv, 0x4);
349 if (waslocked)
350 NVLockVgaCrtcs(pNv, true);
351
352 return !!nv_connector->edid;
353}
354
355static xf86OutputStatus
356nv_output_detect(xf86OutputPtr output)
357{
358 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
359 ScrnInfoPtr pScrn = output->scrn;
360 NVPtr pNv = NVPTR(pScrn);
361 struct nouveau_encoder *det_encoder;
362 xf86OutputStatus ret = XF86OutputStatusDisconnected;
363
364 struct nouveau_encoder *find_encoder_by_type(enum nouveau_encoder_type type)
365 {
366 int i;
367 for (i = 0; i < pNv->vbios->dcb->entries; i++)
368 if (nv_connector->possible_encoders & (1 << i) &&
369 (type == OUTPUT_ANY || pNv->encoders[i].dcb->type == type))
370 return &pNv->encoders[i];
371 return NULL;
372 }
373
374 /* if an LVDS output was ever connected it remains so */
375 if (nv_connector->detected_encoder &&
376 nv_connector->detected_encoder->dcb->type == OUTPUT_LVDS)
377 return XF86OutputStatusConnected;
378
379 if (nv_connector->pDDCBus && edid_sink_connected(output)) {
380 if (MULTIPLE_ENCODERS(nv_connector->possible_encoders)) {
381 if (nv_connector->edid->features.input_type)
382 det_encoder = find_encoder_by_type(OUTPUT_TMDS);
383 else
384 det_encoder = find_encoder_by_type(OUTPUT_ANALOG);
385 } else
386 det_encoder = find_encoder_by_type(OUTPUT_ANY);
387 ret = XF86OutputStatusConnected;
388 } else if ((det_encoder = find_encoder_by_type(OUTPUT_ANALOG))) {
389 /* bind encoder if enabled in xorg.conf */
390 if (output->conf_monitor &&
391 xf86CheckBoolOption(output->conf_monitor->mon_option_lst,
392 "Enable", FALSE))
393 ret = XF86OutputStatusConnected;
394 else if (pNv->gf4_disp_arch) {
395 if (nv_nv17_load_detect(pScrn, det_encoder))
396 ret = XF86OutputStatusConnected;
397 } else
398 if (nv_legacy_load_detect(pScrn))
399 ret = XF86OutputStatusConnected;
400 } else if ((det_encoder = find_encoder_by_type(OUTPUT_LVDS))) {
401 if (det_encoder->dcb->lvdsconf.use_straps_for_mode) {
402 if (nouveau_bios_fp_mode(pScrn, NULL))
403 ret = XF86OutputStatusConnected;
404 } else if (!pNv->vbios->fp_no_ddc &&
405 nouveau_bios_embedded_edid(pScrn)) {
406 nv_connector->edid = xf86InterpretEDID(pScrn->scrnIndex,
407 nouveau_bios_embedded_edid(pScrn));
408 ret = XF86OutputStatusConnected;
409 }
410 }
411
412 if (ret != XF86OutputStatusDisconnected)
413 update_output_fields(output, det_encoder);
414
415 return ret;
416}
417
418static DisplayModePtr
419get_native_mode_from_edid(xf86OutputPtr output, DisplayModePtr edid_modes)
420{
421 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
422 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
423 int max_h_active = 0, max_v_active = 0;
424 int i;
425 DisplayModePtr mode;
426
427 for (i = 0; i < DET_TIMINGS; i++) {
428 struct detailed_timings *dt =
429 &nv_connector->edid->det_mon[i].section.d_timings;
430
431 if (nv_connector->edid->det_mon[i].type != DT)
432 continue;
433 /* Selecting only based on width ok? */
434 if (dt->h_active > max_h_active) {
435 max_h_active = dt->h_active;
436 max_v_active = dt->v_active;
437 }
438 }
439 if (!max_h_active || !max_v_active) /* clearly a joke EDID */
440 for (i = 0; i < STD_TIMINGS; i++) {
441 struct std_timings *st =
442 &nv_connector->edid->timings2[i];
443
444 if (st->hsize > max_h_active) {
445 max_h_active = st->hsize;
446 max_v_active = st->vsize;
447 }
448 }
449 if (!max_h_active || !max_v_active) {
450 NV_ERROR(output->scrn, "EDID too broken to find native mode\n");
451 return NULL;
452 }
453
454 if (nv_encoder->native_mode) {
455 xfree(nv_encoder->native_mode);
456 nv_encoder->native_mode = NULL;
457 }
458
459 for (mode = edid_modes; mode != NULL; mode = mode->next) {
460 if (mode->HDisplay == max_h_active &&
461 mode->VDisplay == max_v_active) {
462 /* Take the preferred mode when it exists. */
463 if (mode->type & M_T_PREFERRED) {
464 nv_encoder->native_mode = xf86DuplicateMode(mode);
465 break;
466 }
467 /* Find the highest refresh mode otherwise. */
468 if (!nv_encoder->native_mode ||
469 (mode->VRefresh > nv_encoder->native_mode->VRefresh)) {
470 if (nv_encoder->native_mode)
471 xfree(nv_encoder->native_mode);
472 mode->type |= M_T_PREFERRED;
473 nv_encoder->native_mode = xf86DuplicateMode(mode);
474 }
475 }
476 }
477
478 return nv_encoder->native_mode;
479}
480
481static DisplayModePtr
482nv_output_get_edid_modes(xf86OutputPtr output)
483{
484 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
485 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
486 DisplayModePtr edid_modes;
487
488 if (IS_DFP(nv_encoder->dcb->type) &&
489 nv_encoder->scaling_mode != SCALE_PANEL)
490 /* the digital scaler is not limited to modes given in the EDID,
491 * so enable the GTF bit in order that the xserver thinks
492 * continuous timing is available and adds the standard modes
493 */
494 nv_connector->edid->features.msc |= 1;
495
496 xf86OutputSetEDID(output, nv_connector->edid);
497 if (!(edid_modes = xf86OutputGetEDIDModes(output)))
498 return edid_modes;
499
500 if (IS_DFP(nv_encoder->dcb->type))
501 if (!get_native_mode_from_edid(output, edid_modes))
502 return NULL;
503 if (nv_encoder->dcb->type == OUTPUT_TMDS)
504 nv_encoder->dual_link = nv_encoder->native_mode->Clock >= 165000;
505
506 return edid_modes;
507}
508
509static DisplayModePtr
510nv_lvds_output_get_modes(xf86OutputPtr output)
511{
512 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
513 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
514 ScrnInfoPtr pScrn = output->scrn;
515 DisplayModeRec mode, *ret_mode = NULL;
516 int clock = 0; /* needs to be zero for straps case */
517 bool dl, if_is_24bit = false;
518
519 /* panels only have one mode, and it doesn't change */
520 if (nv_encoder->native_mode)
521 return xf86DuplicateMode(nv_encoder->native_mode);
522
523 if (nv_encoder->dcb->lvdsconf.use_straps_for_mode) {
524 if (!nouveau_bios_fp_mode(pScrn, &mode))
525 return NULL;
526
527 mode.status = MODE_OK;
528 mode.type = M_T_DRIVER | M_T_PREFERRED;
529 xf86SetModeDefaultName(&mode);
530
531 nv_encoder->native_mode = xf86DuplicateMode(&mode);
532 ret_mode = xf86DuplicateMode(&mode);
533 } else
534 if ((ret_mode = nv_output_get_edid_modes(output)))
535 clock = nv_encoder->native_mode->Clock;
536
537 if (nouveau_bios_parse_lvds_table(pScrn, clock, &dl, &if_is_24bit)) {
538 if (nv_encoder->native_mode) {
539 xfree(nv_encoder->native_mode);
540 nv_encoder->native_mode = NULL;
541 }
542 return NULL;
543 }
544
545 /* because of the pre-existing native mode exit above, this will only
546 * get run at startup (and before create_resources is called in
547 * mode_fixup), so subsequent user dither settings are not overridden
548 */
549 nv_encoder->dithering |= !if_is_24bit;
550 nv_encoder->dual_link = dl;
551
552 return ret_mode;
553}
554
555static int nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
556{
557 struct nouveau_encoder *nv_encoder = to_nouveau_connector(output)->detected_encoder;
558
559 /* mode_valid can be called by someone doing addmode on an output
560 * which is disconnected and so without an encoder; avoid crashing
561 */
562 if (!nv_encoder)
563 return MODE_ERROR;
564
565 if (!output->doubleScanAllowed && mode->Flags & V_DBLSCAN)
566 return MODE_NO_DBLESCAN;
567 if (!output->interlaceAllowed && mode->Flags & V_INTERLACE)
568 return MODE_NO_INTERLACE;
569
570 if (nv_encoder->dcb->type == OUTPUT_ANALOG) {
571 if (nv_encoder->dcb->crtconf.maxfreq) {
572 if (mode->Clock > nv_encoder->dcb->crtconf.maxfreq)
573 return MODE_CLOCK_HIGH;
574 } else
575 if (mode->Clock > 350000)
576 return MODE_CLOCK_HIGH;
577 }
578 /* must have a native mode for fp (except in panel scaling case) */
579 if (IS_DFP(nv_encoder->dcb->type) && !nv_encoder->native_mode &&
580 nv_encoder->scaling_mode != SCALE_PANEL)
581 return MODE_NOCLOCK;
582 if (IS_DFP(nv_encoder->dcb->type) && nv_encoder->native_mode)
583 /* No modes > panel's native res */
584 if (mode->HDisplay > nv_encoder->native_mode->HDisplay ||
585 mode->VDisplay > nv_encoder->native_mode->VDisplay)
586 return MODE_PANEL;
587 if (nv_encoder->dcb->type == OUTPUT_TMDS) {
588 if (nv_encoder->dcb->duallink_possible) {
589 if (mode->Clock > 330000) /* 2x165 MHz */
590 return MODE_CLOCK_HIGH;
591 } else
592 if (mode->Clock > 165000) /* 165 MHz */
593 return MODE_CLOCK_HIGH;
594 }
595
596 return MODE_OK;
597}
598
599static void
600nv_output_destroy(xf86OutputPtr output)
601{
602 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
603 struct nouveau_encoder *nv_encoder;
604 NVPtr pNv = NVPTR(output->scrn);
605 int i;
606
607 if (!nv_connector)
608 return;
609
610 if (nv_connector->edid)
611 xfree(nv_connector->edid);
612 FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder)
613 if (nv_encoder->native_mode)
614 xfree(nv_encoder->native_mode);
615 xfree(nv_connector);
616}
617
618static char * get_current_scaling_name(enum scaling_modes mode)
619{
620 static const struct {
621 char *name;
622 enum scaling_modes mode;
623 } scaling_mode[] = {
624 { "panel", SCALE_PANEL },
625 { "fullscreen", SCALE_FULLSCREEN },
626 { "aspect", SCALE_ASPECT },
627 { "noscale", SCALE_NOSCALE },
628 { NULL, SCALE_INVALID }
629 };
630 int i;
631
632 for (i = 0; scaling_mode[i].name; i++)
633 if (scaling_mode[i].mode == mode)
634 return scaling_mode[i].name;
635
636 return NULL;
637}
638
639static int nv_output_create_prop(xf86OutputPtr output, char *name, Atom *atom,
640 INT32 *rangevals, INT32 cur_val, char *cur_str, Bool do_mode_set)
641{
642 int ret = -ENOMEM;
643 Bool range = rangevals ? TRUE : FALSE;
644
645 if ((*atom = MakeAtom(name, strlen(name), TRUE)) == BAD_RESOURCE)
646 goto fail;
647 if (RRQueryOutputProperty(output->randr_output, *atom))
648 return 0; /* already exists */
649 if ((ret = RRConfigureOutputProperty(output->randr_output, *atom,
650 do_mode_set, range, FALSE, range ? 2 : 0, rangevals)))
651 goto fail;
652 if (range)
653 ret = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER, 32,
654 PropModeReplace, 1, &cur_val, FALSE, do_mode_set);
655 else
656 ret = RRChangeOutputProperty(output->randr_output, *atom, XA_STRING, 8,
657 PropModeReplace, strlen(cur_str), cur_str,
658 FALSE, do_mode_set);
659
660fail:
661 if (ret)
662 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
663 "Creation of %s property failed: %d\n", name, ret);
664
665 return ret;
666}
667
668static Atom dithering_atom, scaling_mode_atom;
669static Atom dv_atom, sharpness_atom;
670
671static void nv_output_create_resources(xf86OutputPtr output)
672{
673 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
674 NVPtr pNv = NVPTR(output->scrn);
675
676 /* may be called before encoder is picked, resources will be created
677 * by update_output_fields()
678 */
679 if (!nv_encoder)
680 return;
681
682 if (IS_DFP(nv_encoder->dcb->type)) {
683 nv_output_create_prop(output, "DITHERING", &dithering_atom,
684 (INT32 []){ 0, 1 }, nv_encoder->dithering, NULL, TRUE);
685 nv_output_create_prop(output, "SCALING_MODE", &scaling_mode_atom,
686 NULL, 0, get_current_scaling_name(nv_encoder->scaling_mode), TRUE);
687 }
688 if (pNv->NVArch >= 0x11 && output->crtc) {
689 struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc);
690 INT32 dv_range[2] = { 0, !pNv->gf4_disp_arch ? 3 : 63 };
691 /* unsure of correct condition here: blur works on my nv34, but not on my nv31 */
692 INT32 is_range[2] = { pNv->NVArch > 0x31 ? -32 : 0, 31 };
693
694 nv_output_create_prop(output, "DIGITAL_VIBRANCE", &dv_atom,
695 dv_range, nv_crtc->saturation, NULL, FALSE);
696 if (pNv->NVArch >= 0x30)
697 nv_output_create_prop(output, "IMAGE_SHARPENING", &sharpness_atom,
698 is_range, nv_crtc->sharpness, NULL, FALSE);
699 }
700}
701
702static Bool
703nv_output_set_property(xf86OutputPtr output, Atom property,
704 RRPropertyValuePtr value)
705{
706 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
707 NVPtr pNv = NVPTR(output->scrn);
708
709 if (property == scaling_mode_atom) {
710 char *name = (char *) value->data;
711 int32_t val;
712
713 if (value->type != XA_STRING || value->format != 8)
714 return FALSE;
715
716 /* Match a string to a scaling mode */
717 val = nv_scaling_mode_lookup(name, value->size);
718 if (val == SCALE_INVALID)
719 return FALSE;
720
721 /* LVDS must always use gpu scaling. */
722 if (val == SCALE_PANEL && nv_encoder->dcb->type == OUTPUT_LVDS)
723 return FALSE;
724
725 nv_encoder->scaling_mode = val;
726 } else if (property == dithering_atom) {
727 int32_t val = *(int32_t *) value->data;
728
729 if (value->type != XA_INTEGER || value->format != 32)
730 return FALSE;
731
732 if (val < 0 || val > 1)
733 return FALSE;
734
735 nv_encoder->dithering = val;
736 } else if (property == dv_atom || property == sharpness_atom) {
737 int32_t val = *(int32_t *) value->data;
738
739 if (value->type != XA_INTEGER || value->format != 32)
740 return FALSE;
741
742 if (!output->crtc)
743 return FALSE;
744
745 if (property == dv_atom) {
746 if (val < 0 || val > (!pNv->gf4_disp_arch ? 3 : 63))
747 return FALSE;
748
749 nv_crtc_set_digital_vibrance(output->crtc, val);
750 } else {
751 if (val < (pNv->NVArch > 0x31 ? -32 : 0) || val > 31)
752 return FALSE;
753
754 nv_crtc_set_image_sharpening(output->crtc, val);
755 }
756 }
757
758 return TRUE;
759}
760
761static Bool
762nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
763 DisplayModePtr adjusted_mode)
764{
765 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
766
767 if (nv_connector->nv_encoder != nv_connector->detected_encoder) {
768 nv_connector->nv_encoder = nv_connector->detected_encoder;
769 if (output->randr_output) {
770 RRDeleteOutputProperty(output->randr_output, dithering_atom);
771 RRDeleteOutputProperty(output->randr_output, scaling_mode_atom);
772 output->funcs->create_resources(output);
773 }
774 }
775
776 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
777
778 /* For internal panels and gpu scaling on DVI we need the native mode */
779 if (IS_DFP(nv_encoder->dcb->type) &&
780 nv_encoder->scaling_mode != SCALE_PANEL) {
781 adjusted_mode->HDisplay = nv_encoder->native_mode->HDisplay;
782 adjusted_mode->HSkew = nv_encoder->native_mode->HSkew;
783 adjusted_mode->HSyncStart = nv_encoder->native_mode->HSyncStart;
784 adjusted_mode->HSyncEnd = nv_encoder->native_mode->HSyncEnd;
785 adjusted_mode->HTotal = nv_encoder->native_mode->HTotal;
786 adjusted_mode->VDisplay = nv_encoder->native_mode->VDisplay;
787 adjusted_mode->VScan = nv_encoder->native_mode->VScan;
788 adjusted_mode->VSyncStart = nv_encoder->native_mode->VSyncStart;
789 adjusted_mode->VSyncEnd = nv_encoder->native_mode->VSyncEnd;
790 adjusted_mode->VTotal = nv_encoder->native_mode->VTotal;
791 adjusted_mode->Clock = nv_encoder->native_mode->Clock;
792 adjusted_mode->Flags = nv_encoder->native_mode->Flags;
793
794 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
795 }
796
797 return TRUE;
798}
799
800static void nv_digital_output_prepare_sel_clk(NVPtr pNv, struct nouveau_encoder *nv_encoder, int head)
801{
802 struct nouveau_mode_state *state = &pNv->set_state;
803 uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000;
804
805 if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
806 return;
807
808 /* SEL_CLK is only used on the primary ramdac
809 * It toggles spread spectrum PLL output and sets the bindings of PLLs
810 * to heads on digital outputs
811 */
812 if (head)
813 state->sel_clk |= bits1618;
814 else
815 state->sel_clk &= ~bits1618;
816
817 /* nv30:
818 * bit 0 NVClk spread spectrum on/off
819 * bit 2 MemClk spread spectrum on/off
820 * bit 4 PixClk1 spread spectrum on/off toggle
821 * bit 6 PixClk2 spread spectrum on/off toggle
822 *
823 * nv40 (observations from bios behaviour and mmio traces):
824 * bits 4&6 as for nv30
825 * bits 5&7 head dependent as for bits 4&6, but do not appear with 4&6;
826 * maybe a different spread mode
827 * bits 8&10 seen on dual-link dvi outputs, purpose unknown (set by POST scripts)
828 * The logic behind turning spread spectrum on/off in the first place,
829 * and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table
830 * entry has the necessary info)
831 */
832 if (nv_encoder->dcb->type == OUTPUT_LVDS && pNv->saved_regs.sel_clk & 0xf0) {
833 int shift = (pNv->saved_regs.sel_clk & 0x50) ? 0 : 1;
834
835 state->sel_clk &= ~0xf0;
836 state->sel_clk |= (head ? 0x40 : 0x10) << shift;
837 }
838}
839
840#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \
841 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \
842 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS)
843#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE | \
844 NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE | \
845 NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE)
846
847static bool is_fpc_off(uint32_t fpc)
848{
849 return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) ==
850 FP_TG_CONTROL_OFF);
851}
852
853static void
854nv_output_prepare(xf86OutputPtr output)
855{
856 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
857 NVPtr pNv = NVPTR(output->scrn);
858 int head = to_nouveau_crtc(output->crtc)->head;
859 struct nouveau_crtc_state *crtcstate = pNv->set_state.head;
860 uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX];
861 uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX];
862
863 output->funcs->dpms(output, DPMSModeOff);
864
865 if (nv_encoder->dcb->type == OUTPUT_ANALOG) {
866 if (NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL) &
867 FP_TG_CONTROL_ON) {
868 /* digital remnants must be cleaned before new crtc
869 * values programmed. delay is time for the vga stuff
870 * to realise it's in control again
871 */
872 NVWriteRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL,
873 FP_TG_CONTROL_OFF);
874 usleep(50000);
875 }
876 /* don't inadvertently turn it on when state written later */
877 crtcstate[head].fp_control = FP_TG_CONTROL_OFF;
878 }
879
880 /* calculate some output specific CRTC regs now, so that they can be
881 * written in nv_crtc_set_mode
882 */
883
884 if (IS_DFP(nv_encoder->dcb->type))
885 nv_digital_output_prepare_sel_clk(pNv, nv_encoder, head);
886
887 /* Some NV4x have unknown values (0x3f, 0x50, 0x54, 0x6b, 0x79, 0x7f)
888 * at LCD__INDEX which we don't alter
889 */
890 if (!(*cr_lcd & 0x44)) {
891 *cr_lcd = IS_DFP(nv_encoder->dcb->type) ? 0x3 : 0x0;
892 if (IS_DFP(nv_encoder->dcb->type) && pNv->twoHeads) {
893 if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP)
894 *cr_lcd |= head ? 0x0 : 0x8;
895 else {
896 *cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30;
897 if (nv_encoder->dcb->type == OUTPUT_LVDS)
898 *cr_lcd |= 0x30;
899 if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) {
900 /* avoid being connected to both crtcs */
901 *cr_lcd_oth &= ~0x30;
902 NVWriteVgaCrtc(pNv, head ^ 1,
903 NV_CIO_CRE_LCD__INDEX,
904 *cr_lcd_oth);
905 }
906 }
907 }
908 }
909}
910
911static void
912nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
913{
914 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
915 ScrnInfoPtr pScrn = output->scrn;
916 NVPtr pNv = NVPTR(pScrn);
917 struct dcb_entry *dcbe = nv_encoder->dcb;
918 int head = to_nouveau_crtc(output->crtc)->head;
919
920 NV_TRACE(pScrn, "%s called for encoder %d\n", __func__, dcbe->index);
921
922 if (pNv->gf4_disp_arch && dcbe->type == OUTPUT_ANALOG) {
923 uint32_t dac_offset = nv_output_ramdac_offset(nv_encoder);
924 uint32_t otherdac;
925 int i;
926
927 /* bit 16-19 are bits that are set on some G70 cards,
928 * but don't seem to have much effect */
929 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset,
930 head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK);
931 /* force any other vga encoders to bind to the other crtc */
932 for (i = 0; i < pNv->vbios->dcb->entries; i++)
933 if (i != dcbe->index && pNv->encoders[i].dcb &&
934 pNv->encoders[i].dcb->type == OUTPUT_ANALOG) {
935 dac_offset = nv_output_ramdac_offset(&pNv->encoders[i]);
936 otherdac = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset);
937 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + dac_offset,
938 (otherdac & ~0x100) | (head ^ 1) << 8);
939 }
940 }
941 if (dcbe->type == OUTPUT_TMDS)
942 run_tmds_table(pScrn, dcbe, head, adjusted_mode->Clock);
943 else if (dcbe->type == OUTPUT_LVDS)
944 call_lvds_script(pScrn, dcbe, head, LVDS_RESET, adjusted_mode->Clock);
945 if (IS_DFP(dcbe->type))
946 /* update fp_control state for any changes made by scripts,
947 * so correct value is written at DPMS on */
948 pNv->set_state.head[head].fp_control =
949 NVReadRAMDAC(pNv, head, NV_PRAMDAC_FP_TG_CONTROL);
950
951 /* This could use refinement for flatpanels, but it should work this way */
952 if (pNv->NVArch < 0x44)
953 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0xf0000000);
954 else
955 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_TEST_CONTROL + nv_output_ramdac_offset(nv_encoder), 0x00100000);
956}
957
958static void
959nv_output_commit(xf86OutputPtr output)
960{
961 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
962 ScrnInfoPtr pScrn = output->scrn;
963 struct nouveau_crtc *nv_crtc = to_nouveau_crtc(output->crtc);
964
965 output->funcs->dpms(output, DPMSModeOn);
966
967 NV_TRACE(pScrn, "Output %s is running on CRTC %d using output %c\n",
968 output->name, nv_crtc->head, '@' + ffs(nv_encoder->dcb->or));
969}
970
971static void dpms_update_fp_control(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
972{
973 NVPtr pNv = NVPTR(pScrn);
974 struct nouveau_crtc *nv_crtc;
975 uint32_t *fpc;
976 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
977 int i;
978
979 if (mode == DPMSModeOn) {
980 nv_crtc = to_nouveau_crtc(crtc);
981 fpc = &nv_crtc->state->fp_control;
982
983 if (is_fpc_off(*fpc))
984 /* using saved value is ok, as (is_digital && dpms_on &&
985 * fp_control==OFF) is (at present) *only* true when
986 * fpc's most recent change was by below "off" code
987 */
988 *fpc = nv_crtc->dpms_saved_fp_control;
989
990 nv_crtc->fp_users |= 1 << nv_encoder->dcb->index;
991 NVWriteRAMDAC(pNv, nv_crtc->head, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
992 } else
993 for (i = 0; i < xf86_config->num_crtc; i++) {
994 nv_crtc = to_nouveau_crtc(xf86_config->crtc[i]);
995 fpc = &nv_crtc->state->fp_control;
996
997 nv_crtc->fp_users &= ~(1 << nv_encoder->dcb->index);
998 if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
999 nv_crtc->dpms_saved_fp_control = *fpc;
1000 /* cut the FP output */
1001 *fpc &= ~FP_TG_CONTROL_ON;
1002 *fpc |= FP_TG_CONTROL_OFF;
1003 NVWriteRAMDAC(pNv, nv_crtc->head,
1004 NV_PRAMDAC_FP_TG_CONTROL, *fpc);
1005 }
1006 }
1007}
1008
1009static bool is_powersaving_dpms(int mode)
1010{
1011 return (mode == DPMSModeStandby || mode == DPMSModeSuspend ||
1012 mode == DPMSModeOff);
1013}
1014
1015static void
1016lvds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
1017{
1018 NVPtr pNv = NVPTR(pScrn);
1019 bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms);
1020
1021 if (nv_encoder->last_dpms == mode)
1022 return;
1023 nv_encoder->last_dpms = mode;
1024
1025 NV_TRACE(pScrn, "Setting dpms mode %d on lvds encoder (output %d)\n",
1026 mode, nv_encoder->dcb->index);
1027
1028 if (was_powersaving && is_powersaving_dpms(mode))
1029 return;
1030
1031 if (nv_encoder->dcb->lvdsconf.use_power_scripts) {
1032 /* when removing an output, crtc may not be set, but PANEL_OFF
1033 * must still be run
1034 */
1035 int head = crtc ? to_nouveau_crtc(crtc)->head :
1036 nv_get_digital_bound_head(pNv, nv_encoder->dcb->or);
1037
1038 if (mode == DPMSModeOn)
1039 call_lvds_script(pScrn, nv_encoder->dcb, head,
1040 LVDS_PANEL_ON, nv_encoder->native_mode->Clock);
1041 else
1042 /* pxclk of 0 is fine for PANEL_OFF, and for a
1043 * disconnected LVDS encoder there is no native_mode
1044 */
1045 call_lvds_script(pScrn, nv_encoder->dcb, head,
1046 LVDS_PANEL_OFF, 0);
1047 }
1048
1049 dpms_update_fp_control(pScrn, nv_encoder, crtc, mode);
1050
1051 if (mode == DPMSModeOn)
1052 nv_digital_output_prepare_sel_clk(pNv, nv_encoder, to_nouveau_crtc(crtc)->head);
1053 else {
1054 pNv->set_state.sel_clk = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK);
1055 pNv->set_state.sel_clk &= ~0xf0;
1056 }
1057 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_SEL_CLK, pNv->set_state.sel_clk);
1058}
1059
1060static void
1061vga_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
1062{
1063 NVPtr pNv = NVPTR(pScrn);
1064
1065 if (nv_encoder->last_dpms == mode)
1066 return;
1067 nv_encoder->last_dpms = mode;
1068
1069 NV_TRACE(pScrn, "Setting dpms mode %d on vga encoder (output %d)\n",
1070 mode, nv_encoder->dcb->index);
1071
1072 if (pNv->gf4_disp_arch) {
1073 uint32_t outputval = NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder));
1074
1075 if (mode == DPMSModeOff)
1076 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
1077 outputval & ~NV_PRAMDAC_DACCLK_SEL_DACCLK);
1078 else if (mode == DPMSModeOn)
1079 NVWriteRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
1080 outputval | NV_PRAMDAC_DACCLK_SEL_DACCLK);
1081 }
1082}
1083
1084static void
1085tmds_encoder_dpms(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder, xf86CrtcPtr crtc, int mode)
1086{
1087 if (nv_encoder->last_dpms == mode)
1088 return;
1089 nv_encoder->last_dpms = mode;
1090
1091 NV_TRACE(pScrn, "Setting dpms mode %d on tmds encoder (output %d)\n",
1092 mode, nv_encoder->dcb->index);
1093
1094 dpms_update_fp_control(pScrn, nv_encoder, crtc, mode);
1095}
1096
1097static void nv_output_dpms(xf86OutputPtr output, int mode)
1098{
1099 struct nouveau_connector *nv_connector = to_nouveau_connector(output);
1100 struct nouveau_encoder *nv_encoder = to_nouveau_encoder(output);
1101 ScrnInfoPtr pScrn = output->scrn;
1102 xf86CrtcPtr crtc = output->crtc;
1103 NVPtr pNv = NVPTR(pScrn);
1104 int i;
1105 void (* const encoder_dpms[4])(ScrnInfoPtr, struct nouveau_encoder *, xf86CrtcPtr, int) =
1106 /* index matches DCB type */
1107 { vga_encoder_dpms, NULL, tmds_encoder_dpms, lvds_encoder_dpms };
1108
1109 struct nouveau_encoder *nv_encoder_i;
1110 FOR_EACH_ENCODER_IN_CONNECTOR(i, nv_connector, nv_encoder_i)
1111 if (nv_encoder_i != nv_encoder)
1112 encoder_dpms[nv_encoder_i->dcb->type](pScrn, nv_encoder_i, crtc, DPMSModeOff);
1113
1114 if (nv_encoder) /* may be called before encoder is picked, but iteration above solves it */
1115 encoder_dpms[nv_encoder->dcb->type](pScrn, nv_encoder, crtc, mode);
1116}
1117
1118void nv_encoder_save(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
1119{
1120 NVPtr pNv = NVPTR(pScrn);
1121
1122 if (!nv_encoder->dcb) /* uninitialised encoder */
1123 return;
1124
1125 if (pNv->gf4_disp_arch && nv_encoder->dcb->type == OUTPUT_ANALOG)
1126 nv_encoder->restore.output =
1127 NVReadRAMDAC(pNv, 0, NV_PRAMDAC_DACCLK +
1128 nv_output_ramdac_offset(nv_encoder));
1129 if (pNv->twoHeads && IS_DFP(nv_encoder->dcb->type))
1130 nv_encoder->restore.head =
1131 nv_get_digital_bound_head(pNv, nv_encoder->dcb->or);
1132}
1133
1134void nv_encoder_restore(ScrnInfoPtr pScrn, struct nouveau_encoder *nv_encoder)
1135{
1136 NVPtr pNv = NVPTR(pScrn);
1137 int head = nv_encoder->restore.head;
1138
1139 if (!nv_encoder->dcb) /* uninitialised encoder */
1140 return;
1141
1142 if (pNv->gf4_disp_arch && nv_encoder->dcb->type == OUTPUT_ANALOG)
1143 NVWriteRAMDAC(pNv, 0,
1144 NV_PRAMDAC_DACCLK + nv_output_ramdac_offset(nv_encoder),
1145 nv_encoder->restore.output);
1146 if (nv_encoder->dcb->type == OUTPUT_LVDS)
1147 call_lvds_script(pScrn, nv_encoder->dcb, head, LVDS_PANEL_ON,
1148 nv_encoder->native_mode->Clock);
1149 if (nv_encoder->dcb->type == OUTPUT_TMDS) {
1150 int clock = nouveau_hw_pllvals_to_clk
1151 (&pNv->saved_regs.head[head].pllvals);
1152
1153 run_tmds_table(pScrn, nv_encoder->dcb, head, clock);
1154 }
1155
1156 nv_encoder->last_dpms = NV_DPMS_CLEARED;
1157}
1158
1159static const xf86OutputFuncsRec nv_output_funcs = {
1160 .dpms = nv_output_dpms,
1161 .mode_valid = nv_output_mode_valid,
1162 .mode_fixup = nv_output_mode_fixup,
1163 .mode_set = nv_output_mode_set,
1164 .detect = nv_output_detect,
1165 .get_modes = nv_output_get_edid_modes,
1166 .destroy = nv_output_destroy,
1167 .prepare = nv_output_prepare,
1168 .commit = nv_output_commit,
1169 .create_resources = nv_output_create_resources,
1170 .set_property = nv_output_set_property,
1171};
1172
1173static const xf86OutputFuncsRec nv_lvds_output_funcs = {
1174 .dpms = nv_output_dpms,
1175 .mode_valid = nv_output_mode_valid,
1176 .mode_fixup = nv_output_mode_fixup,
1177 .mode_set = nv_output_mode_set,
1178 .detect = nv_output_detect,
1179 .get_modes = nv_lvds_output_get_modes,
1180 .destroy = nv_output_destroy,
1181 .prepare = nv_output_prepare,
1182 .commit = nv_output_commit,
1183 .create_resources = nv_output_create_resources,
1184 .set_property = nv_output_set_property,
1185};
1186
1187static void
1188nv_add_encoder(ScrnInfoPtr pScrn, struct dcb_entry *dcbent)
1189{
1190 NVPtr pNv = NVPTR(pScrn);
1191 struct nouveau_encoder *nv_encoder = &pNv->encoders[dcbent->index];
1192
1193 nv_encoder->dcb = dcbent;
1194 nv_encoder->last_dpms = NV_DPMS_CLEARED;
1195 nv_encoder->dithering = pNv->FPDither;
1196 if (pNv->FpScale && pNv->gf4_disp_arch) /* GPU Scaling */
1197 nv_encoder->scaling_mode = SCALE_ASPECT;
1198 else if (nv_encoder->dcb->type == OUTPUT_LVDS)
1199 nv_encoder->scaling_mode = SCALE_NOSCALE;
1200 else
1201 nv_encoder->scaling_mode = SCALE_PANEL;
1202 if (xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE)) {
1203 nv_encoder->scaling_mode = nv_scaling_mode_lookup(xf86GetOptValString(pNv->Options, OPTION_SCALING_MODE), -1);
1204 if (nv_encoder->scaling_mode == SCALE_INVALID)
1205 nv_encoder->scaling_mode = SCALE_ASPECT; /* default */
1206 }
1207}
1208
1209static void
1210nv_add_connector(ScrnInfoPtr pScrn, int i2c_index, int encoders, const xf86OutputFuncsRec *output_funcs, char *outputname)
1211{
1212 NVPtr pNv = NVPTR(pScrn);
1213 xf86OutputPtr output;
1214 struct nouveau_connector *nv_connector;
1215
1216 if (!(output = xf86OutputCreate(pScrn, output_funcs, outputname)))
1217 return;
1218 if (!(nv_connector = xcalloc(1, sizeof (struct nouveau_connector)))) {
1219 xf86OutputDestroy(output);
1220 return;
1221 }
1222
1223 output->driver_private = nv_connector;
1224
1225 if (i2c_index < 0xf)
1226 NV_I2CInit(pScrn, &nv_connector->pDDCBus, &pNv->vbios->dcb->i2c[i2c_index], xstrdup(outputname));
1227 nv_connector->possible_encoders = encoders;
1228}
1229
1230void NvSetupOutputs(ScrnInfoPtr pScrn)
1231{
1232 NVPtr pNv = NVPTR(pScrn);
1233 struct parsed_dcb *dcb = pNv->vbios->dcb;
1234 uint16_t connectors[0x10] = { 0 };
1235 int i, vga_count = 0, dvid_count = 0, dvii_count = 0, lvds_count = 0;
1236
1237 if (!(pNv->encoders = xcalloc(dcb->entries, sizeof (struct nouveau_encoder))))
1238 return;
1239
1240 for (i = 0; i < dcb->entries; i++) {
1241 struct dcb_entry *dcbent = &dcb->entry[i];
1242
1243 if (dcbent->type == OUTPUT_TV)
1244 continue;
1245 if (dcbent->type > 3) {
1246 NV_WARN(pScrn, "DCB type %d not known\n", dcbent->type);
1247 continue;
1248 }
1249
1250 connectors[dcbent->i2c_index] |= 1 << i;
1251
1252 nv_add_encoder(pScrn, dcbent);
1253 }
1254
1255 for (i = 0; i < dcb->entries; i++) {
1256 struct dcb_entry *dcbent = &dcb->entry[i];
1257 int i2c_index = dcbent->i2c_index;
1258 uint16_t encoders = connectors[i2c_index];
1259 char outputname[20];
1260 xf86OutputFuncsRec const *funcs = &nv_output_funcs;
1261
1262 if (!encoders)
1263 continue;
1264
1265 switch (dcbent->type) {
1266 case OUTPUT_ANALOG:
1267 if (!MULTIPLE_ENCODERS(encoders))
1268 sprintf(outputname, "VGA-%d", vga_count++);
1269 else
1270 sprintf(outputname, "DVI-I-%d", dvii_count++);
1271 break;
1272 case OUTPUT_TMDS:
1273 if (!MULTIPLE_ENCODERS(encoders))
1274 sprintf(outputname, "DVI-D-%d", dvid_count++);
1275 else
1276 sprintf(outputname, "DVI-I-%d", dvii_count++);
1277 break;
1278 case OUTPUT_LVDS:
1279 sprintf(outputname, "LVDS-%d", lvds_count++);
1280 funcs = &nv_lvds_output_funcs;
1281 /* don't create i2c adapter when lvds ddc not allowed */
1282 if (dcbent->lvdsconf.use_straps_for_mode ||
1283 pNv->vbios->fp_no_ddc)
1284 i2c_index = 0xf;
1285 break;
1286 default:
1287 continue;
1288 }
1289
1290 nv_add_connector(pScrn, i2c_index, encoders, funcs, outputname);
1291 connectors[i2c_index] = 0; /* avoid connectors being added multiply */
1292 }
1293}