radeon_output.c revision b7e1c893
1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <string.h>
34#include <stdio.h>
35
36/* X and server generic header files */
37#include "xf86.h"
38#include "xf86_OSproc.h"
39#include "vgaHW.h"
40#include "xf86Modes.h"
41
42/* Driver data structures */
43#include "radeon.h"
44#include "radeon_reg.h"
45#include "radeon_macros.h"
46#include "radeon_probe.h"
47#include "radeon_version.h"
48#include "radeon_tv.h"
49#include "radeon_atombios.h"
50
51const char *encoder_name[34] = {
52    "NONE",
53    "INTERNAL_LVDS",
54    "INTERNAL_TMDS1",
55    "INTERNAL_TMDS2",
56    "INTERNAL_DAC1",
57    "INTERNAL_DAC2",
58    "INTERNAL_SDVOA",
59    "INTERNAL_SDVOB",
60    "SI170B",
61    "CH7303",
62    "CH7301",
63    "INTERNAL_DVO1",
64    "EXTERNAL_SDVOA",
65    "EXTERNAL_SDVOB",
66    "TITFP513",
67    "INTERNAL_LVTM1",
68    "VT1623",
69    "HDMI_SI1930",
70    "HDMI_INTERNAL",
71    "INTERNAL_KLDSCP_TMDS1",
72    "INTERNAL_KLDSCP_DVO1",
73    "INTERNAL_KLDSCP_DAC1",
74    "INTERNAL_KLDSCP_DAC2",
75    "SI178",
76    "MVPU_FPGA",
77    "INTERNAL_DDI",
78    "VT1625",
79    "HDMI_SI1932",
80    "DP_AN9801",
81    "DP_DP501",
82    "INTERNAL_UNIPHY",
83    "INTERNAL_KLDSCP_LVTMA",
84    "INTERNAL_UNIPHY1",
85    "INTERNAL_UNIPHY2",
86};
87
88const char *ConnectorTypeName[17] = {
89  "None",
90  "VGA",
91  "DVI-I",
92  "DVI-D",
93  "DVI-A",
94  "S-video",
95  "Composite",
96  "LVDS",
97  "Digital",
98  "SCART",
99  "HDMI-A",
100  "HDMI-B",
101  "Unsupported",
102  "Unsupported",
103  "DIN",
104  "DisplayPort",
105  "Unsupported"
106};
107
108extern void atombios_output_mode_set(xf86OutputPtr output,
109				     DisplayModePtr mode,
110				     DisplayModePtr adjusted_mode);
111extern void atombios_output_dpms(xf86OutputPtr output, int mode);
112extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output);
113extern AtomBiosResult
114atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock);
115static void
116radeon_bios_output_dpms(xf86OutputPtr output, int mode);
117static void
118radeon_bios_output_crtc(xf86OutputPtr output);
119static void
120radeon_bios_output_lock(xf86OutputPtr output, Bool lock);
121
122void RADEONPrintPortMap(ScrnInfoPtr pScrn)
123{
124    RADEONInfoPtr info = RADEONPTR(pScrn);
125    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
126    RADEONOutputPrivatePtr radeon_output;
127    xf86OutputPtr output;
128    int o;
129
130    for (o = 0; o < xf86_config->num_output; o++) {
131	output = xf86_config->output[o];
132	radeon_output = output->driver_private;
133
134	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o);
135	ErrorF("  XRANDR name: %s\n", output->name);
136	ErrorF("  Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]);
137	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
138	    ErrorF("  CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
139	if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
140	    ErrorF("  CRT2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id]);
141	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
142	    ErrorF("  LCD1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_LCD1_INDEX]->encoder_id]);
143	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
144	    ErrorF("  DFP1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP1_INDEX]->encoder_id]);
145	if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
146	    ErrorF("  DFP2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP2_INDEX]->encoder_id]);
147	if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
148	    ErrorF("  DFP3: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP3_INDEX]->encoder_id]);
149	if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
150	    ErrorF("  DFP4: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP4_INDEX]->encoder_id]);
151	if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
152	    ErrorF("  DFP5: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP5_INDEX]->encoder_id]);
153	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
154	    ErrorF("  TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]);
155	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
156	    ErrorF("  CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
157	ErrorF("  DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
158    }
159
160}
161
162static void
163radeon_set_active_device(xf86OutputPtr output)
164{
165    RADEONOutputPrivatePtr radeon_output = output->driver_private;
166
167    radeon_output->active_device = 0;
168
169    switch (radeon_output->MonType) {
170    case MT_DP:
171    case MT_DFP:
172	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
173	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
174	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
175	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
176	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
177	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
178	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
179	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
180	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
181	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
182	break;
183    case MT_CRT:
184	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
185	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
186	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
187	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
188	break;
189    case MT_LCD:
190	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
191	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
192	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
193	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
194	break;
195    case MT_STV:
196    case MT_CTV:
197	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
198	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
199	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
200	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
201	break;
202    case MT_CV:
203	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
204	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
205	break;
206    default:
207	ErrorF("Unhandled monitor type %d\n", radeon_output->MonType);
208	radeon_output->active_device = 0;
209    }
210}
211
212static RADEONMonitorType
213radeon_ddc_connected(xf86OutputPtr output)
214{
215    ScrnInfoPtr pScrn        = output->scrn;
216    RADEONInfoPtr info = RADEONPTR(pScrn);
217    RADEONMonitorType MonType = MT_NONE;
218    xf86MonPtr MonInfo = NULL;
219    RADEONOutputPrivatePtr radeon_output = output->driver_private;
220
221    if (radeon_output->pI2CBus) {
222	/* RV410 RADEON_GPIO_VGA_DDC seems to only work via hw i2c
223	 * We may want to extend this to other cases if the need arises...
224	 */
225	if ((info->ChipFamily == CHIP_FAMILY_RV410) &&
226	    (radeon_output->ddc_i2c.mask_clk_reg == RADEON_GPIO_VGA_DDC) &&
227	    info->IsAtomBios)
228	    MonInfo = radeon_atom_get_edid(output);
229	else if (info->get_hardcoded_edid_from_bios) {
230	    MonInfo = RADEONGetHardCodedEDIDFromBIOS(output);
231	    if (MonInfo == NULL) {
232		RADEONI2CDoLock(output, TRUE);
233		MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
234		RADEONI2CDoLock(output, FALSE);
235	    }
236	} else {
237	    RADEONI2CDoLock(output, TRUE);
238	    MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
239	    RADEONI2CDoLock(output, FALSE);
240	}
241    }
242    if (MonInfo) {
243	switch (radeon_output->ConnectorType) {
244	case CONNECTOR_LVDS:
245	    MonType = MT_LCD;
246	    break;
247	case CONNECTOR_DVI_D:
248	case CONNECTOR_HDMI_TYPE_A:
249	case CONNECTOR_HDMI_TYPE_B:
250	    if (radeon_output->shared_ddc) {
251		if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI/HDMI/etc. */
252		    MonType = MT_DFP;
253		else
254		    MonType = MT_NONE;
255	    } else
256		MonType = MT_DFP;
257	    break;
258	case CONNECTOR_DISPLAY_PORT:
259	    /*
260	     * XXX wrong. need to infer based on whether we got DDC from I2C
261	     * or AUXCH.
262	     */
263	    MonType = MT_DFP;
264	case CONNECTOR_DVI_I:
265	    if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI */
266		MonType = MT_DFP;
267	    else
268		MonType = MT_CRT;
269	    break;
270	case CONNECTOR_VGA:
271	case CONNECTOR_DVI_A:
272	default:
273	    if (radeon_output->shared_ddc) {
274		if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */
275		    MonType = MT_NONE;
276		else
277		    MonType = MT_CRT;
278	    } else
279		MonType = MT_CRT;
280	    break;
281	}
282
283	if (MonType != MT_NONE)
284	    if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE))
285		xf86OutputSetEDID(output, MonInfo);
286    } else
287	MonType = MT_NONE;
288
289    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
290	       "Output: %s, Detected Monitor Type: %d\n", output->name, MonType);
291
292    return MonType;
293}
294
295#ifndef __powerpc__
296
297static RADEONMonitorType
298RADEONDetectLidStatus(ScrnInfoPtr pScrn)
299{
300    RADEONInfoPtr info = RADEONPTR(pScrn);
301    RADEONMonitorType MonType = MT_NONE;
302#ifdef __linux__
303    char lidline[50];  /* 50 should be sufficient for our purposes */
304    FILE *f = fopen ("/proc/acpi/button/lid/LID/state", "r");
305
306    if (f != NULL) {
307	while (fgets(lidline, sizeof lidline, f)) {
308	    if (!strncmp(lidline, "state:", strlen ("state:"))) {
309		if (strstr(lidline, "open")) {
310		    fclose(f);
311		    ErrorF("proc lid open\n");
312		    return MT_LCD;
313		}
314		else if (strstr(lidline, "closed")) {
315		    fclose(f);
316		    ErrorF("proc lid closed\n");
317		    return MT_NONE;
318		}
319	    }
320	}
321	fclose(f);
322    }
323#endif
324
325    if (!info->IsAtomBios) {
326	unsigned char *RADEONMMIO = info->MMIO;
327
328	/* see if the lid is closed -- only works at boot */
329	if (INREG(RADEON_BIOS_6_SCRATCH) & 0x10)
330	    MonType = MT_NONE;
331	else
332	    MonType = MT_LCD;
333    } else
334	MonType = MT_LCD;
335
336    return MonType;
337}
338
339#endif /* __powerpc__ */
340
341static void
342radeon_dpms(xf86OutputPtr output, int mode)
343{
344    RADEONInfoPtr info = RADEONPTR(output->scrn);
345    RADEONOutputPrivatePtr radeon_output = output->driver_private;
346
347    if ((mode == DPMSModeOn) && radeon_output->enabled)
348	return;
349
350    if (IS_AVIVO_VARIANT || info->r4xx_atom) {
351	atombios_output_dpms(output, mode);
352    } else {
353	legacy_output_dpms(output, mode);
354    }
355    radeon_bios_output_dpms(output, mode);
356
357    if (mode == DPMSModeOn)
358	radeon_output->enabled = TRUE;
359    else
360	radeon_output->enabled = FALSE;
361
362}
363
364static void
365radeon_save(xf86OutputPtr output)
366{
367
368}
369
370static void
371radeon_restore(xf86OutputPtr restore)
372{
373
374}
375
376static int
377radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
378{
379    RADEONOutputPrivatePtr radeon_output = output->driver_private;
380    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
381    ScrnInfoPtr pScrn = output->scrn;
382    RADEONInfoPtr info = RADEONPTR(pScrn);
383    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
384
385    /*
386     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
387     * XXX should really do this for all chips by properly computing
388     * memory bandwidth and an overhead factor.
389     */
390    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
391	if (xf86ModeBandwidth(pMode, pScrn->bitsPerPixel) > 300)
392	    return MODE_BANDWIDTH;
393    }
394
395    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
396	if (IS_AVIVO_VARIANT)
397	    return MODE_OK;
398	else {
399	    /* FIXME: Update when more modes are added */
400	    if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
401		return MODE_OK;
402	    else
403		return MODE_CLOCK_RANGE;
404	}
405    }
406
407    /* single link DVI check */
408    if (pMode->Clock > 165000 && radeon_output->MonType == MT_DFP) {
409	/* DP->DVI converter */
410	if (radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT)
411	    return MODE_CLOCK_HIGH;
412
413	/* XXX some HDMI can do better than 165MHz on a link */
414	if (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A)
415	    return MODE_CLOCK_HIGH;
416
417	/* XXX some R300 and R400 can actually do this */
418	if (!IS_AVIVO_VARIANT)
419	    return MODE_CLOCK_HIGH;
420
421	/* XXX and some AVIVO can't */
422    }
423
424    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
425	if (radeon_output->rmx_type == RMX_OFF) {
426	    if (pMode->HDisplay != native_mode->PanelXRes ||
427		pMode->VDisplay != native_mode->PanelYRes)
428		return MODE_PANEL;
429	}
430	if (pMode->HDisplay > native_mode->PanelXRes ||
431	    pMode->VDisplay > native_mode->PanelYRes)
432	    return MODE_PANEL;
433    }
434
435    return MODE_OK;
436}
437
438static Bool
439radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
440		    DisplayModePtr adjusted_mode)
441{
442    RADEONInfoPtr info = RADEONPTR(output->scrn);
443    RADEONOutputPrivatePtr radeon_output = output->driver_private;
444    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
445
446    radeon_output->Flags &= ~RADEON_USE_RMX;
447
448    /*
449     *  Refresh the Crtc values without INTERLACE_HALVE_V
450     *  Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does?
451     */
452    xf86SetModeCrtc(adjusted_mode, 0);
453
454    /* decide if we are using RMX */
455    if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT))
456	&& radeon_output->rmx_type != RMX_OFF) {
457	xf86CrtcPtr crtc = output->crtc;
458	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
459
460	if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) {
461	    if (mode->HDisplay < native_mode->PanelXRes ||
462		mode->VDisplay < native_mode->PanelYRes) {
463		radeon_output->Flags |= RADEON_USE_RMX;
464		if (IS_AVIVO_VARIANT) {
465		    /* set to the panel's native mode */
466		    adjusted_mode->HDisplay = native_mode->PanelXRes;
467		    adjusted_mode->VDisplay = native_mode->PanelYRes;
468		    adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank;
469		    adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus;
470		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth;
471		    adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank;
472		    adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus;
473		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth;
474		    /* update crtc values */
475		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
476		    /* adjust crtc values */
477		    adjusted_mode->CrtcHDisplay = native_mode->PanelXRes;
478		    adjusted_mode->CrtcVDisplay = native_mode->PanelYRes;
479		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank;
480		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus;
481		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth;
482		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank;
483		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus;
484		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth;
485		} else {
486		    /* set to the panel's native mode */
487		    adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank;
488		    adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus;
489		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth;
490		    adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank;
491		    adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus;
492		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth;
493		    adjusted_mode->Clock = native_mode->DotClock;
494		    /* update crtc values */
495		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
496		    /* adjust crtc values */
497		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank;
498		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus;
499		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth;
500		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank;
501		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus;
502		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth;
503		}
504		adjusted_mode->Clock = native_mode->DotClock;
505		adjusted_mode->Flags = native_mode->Flags;
506	    }
507	}
508    }
509
510    if (IS_AVIVO_VARIANT) {
511	/* hw bug */
512	if ((mode->Flags & V_INTERLACE)
513	    && (adjusted_mode->CrtcVSyncStart < (adjusted_mode->CrtcVDisplay + 2)))
514	    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + 2;
515    }
516
517    return TRUE;
518}
519
520static void
521radeon_mode_prepare(xf86OutputPtr output)
522{
523    radeon_bios_output_lock(output, TRUE);
524    radeon_dpms(output, DPMSModeOff);
525}
526
527static void
528radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
529		DisplayModePtr adjusted_mode)
530{
531    RADEONInfoPtr info = RADEONPTR(output->scrn);
532
533    if (IS_AVIVO_VARIANT || info->r4xx_atom)
534	atombios_output_mode_set(output, mode, adjusted_mode);
535    else
536	legacy_output_mode_set(output, mode, adjusted_mode);
537    radeon_bios_output_crtc(output);
538
539}
540
541static void
542radeon_mode_commit(xf86OutputPtr output)
543{
544    radeon_dpms(output, DPMSModeOn);
545    radeon_bios_output_lock(output, FALSE);
546}
547
548static void
549radeon_bios_output_lock(xf86OutputPtr output, Bool lock)
550{
551    ScrnInfoPtr	    pScrn = output->scrn;
552    RADEONInfoPtr info = RADEONPTR(pScrn);
553    unsigned char *RADEONMMIO = info->MMIO;
554    RADEONSavePtr save = info->ModeReg;
555
556    if (info->IsAtomBios) {
557	if (lock) {
558	    save->bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
559	} else {
560	    save->bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
561	}
562    } else {
563	if (lock) {
564	    save->bios_6_scratch |= RADEON_DRIVER_CRITICAL;
565	} else {
566	    save->bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
567	}
568    }
569    if (info->ChipFamily >= CHIP_FAMILY_R600)
570	OUTREG(R600_BIOS_6_SCRATCH, save->bios_6_scratch);
571    else
572	OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch);
573}
574
575static void
576radeon_bios_output_dpms(xf86OutputPtr output, int mode)
577{
578    ScrnInfoPtr	    pScrn = output->scrn;
579    RADEONInfoPtr info = RADEONPTR(pScrn);
580    RADEONOutputPrivatePtr radeon_output = output->driver_private;
581    unsigned char *RADEONMMIO = info->MMIO;
582    RADEONSavePtr save = info->ModeReg;
583
584    if (info->IsAtomBios) {
585	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
586	    if (mode == DPMSModeOn)
587		save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
588	    else
589		save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
590	} else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) {
591	    if (mode == DPMSModeOn)
592		save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
593	    else
594		save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
595	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
596	    if (mode == DPMSModeOn)
597		save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
598	    else
599		save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
600	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
601	    if (mode == DPMSModeOn)
602		save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
603	    else
604		save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
605	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
606	    if (mode == DPMSModeOn)
607		save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
608	    else
609		save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
610	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
611	    if (mode == DPMSModeOn)
612		save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
613	    else
614		save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
615	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
616	    if (mode == DPMSModeOn)
617		save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
618	    else
619		save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
620	} else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) {
621	    if (mode == DPMSModeOn)
622		save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
623	    else
624		save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
625	} else if (radeon_output->active_device & ATOM_DEVICE_DFP4_SUPPORT) {
626	    if (mode == DPMSModeOn)
627		save->bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;
628	    else
629		save->bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;
630	} else if (radeon_output->active_device & ATOM_DEVICE_DFP5_SUPPORT) {
631	    if (mode == DPMSModeOn)
632		save->bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;
633	    else
634		save->bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;
635	}
636	if (info->ChipFamily >= CHIP_FAMILY_R600)
637	    OUTREG(R600_BIOS_2_SCRATCH, save->bios_2_scratch);
638	else
639	    OUTREG(RADEON_BIOS_2_SCRATCH, save->bios_2_scratch);
640    } else {
641	if (mode == DPMSModeOn) {
642	    save->bios_6_scratch &= ~(RADEON_DPMS_MASK | RADEON_SCREEN_BLANKING);
643	    save->bios_6_scratch |= RADEON_DPMS_ON;
644	} else {
645	    save->bios_6_scratch &= ~RADEON_DPMS_MASK;
646	    save->bios_6_scratch |= (RADEON_DPMS_OFF | RADEON_SCREEN_BLANKING);
647	}
648	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
649	    if (mode == DPMSModeOn)
650		save->bios_6_scratch |= RADEON_TV_DPMS_ON;
651	    else
652		save->bios_6_scratch &= ~RADEON_TV_DPMS_ON;
653	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
654	    if (mode == DPMSModeOn)
655		save->bios_6_scratch |= RADEON_CRT_DPMS_ON;
656	    else
657		save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
658	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
659	    if (mode == DPMSModeOn)
660		save->bios_6_scratch |= RADEON_CRT_DPMS_ON;
661	    else
662		save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
663	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
664	    if (mode == DPMSModeOn)
665		save->bios_6_scratch |= RADEON_LCD_DPMS_ON;
666	    else
667		save->bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
668	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
669	    if (mode == DPMSModeOn)
670		save->bios_6_scratch |= RADEON_DFP_DPMS_ON;
671	    else
672		save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
673	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
674	    if (mode == DPMSModeOn)
675		save->bios_6_scratch |= RADEON_DFP_DPMS_ON;
676	    else
677		save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
678	}
679	OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch);
680    }
681}
682
683static void
684radeon_bios_output_crtc(xf86OutputPtr output)
685{
686    ScrnInfoPtr	    pScrn = output->scrn;
687    RADEONInfoPtr info = RADEONPTR(pScrn);
688    RADEONOutputPrivatePtr radeon_output = output->driver_private;
689    unsigned char *RADEONMMIO = info->MMIO;
690    RADEONSavePtr save = info->ModeReg;
691    xf86CrtcPtr crtc = output->crtc;
692    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
693
694    if (info->IsAtomBios) {
695	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
696	    save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
697	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 18);
698	} else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) {
699	    save->bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
700	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 24);
701	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
702	    save->bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
703	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 16);
704	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
705	    save->bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
706	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 20);
707	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
708	    save->bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
709	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 17);
710	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
711	    save->bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
712	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 19);
713	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
714	    save->bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
715	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 23);
716	} else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) {
717	    save->bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
718	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 25);
719	}
720	if (info->ChipFamily >= CHIP_FAMILY_R600)
721	    OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch);
722	else
723	    OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch);
724    } else {
725	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
726	    save->bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
727	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT);
728	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
729	    save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
730	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT);
731	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
732	    save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
733	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT);
734	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
735	    save->bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
736	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT);
737	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
738	    save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
739	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT);
740	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
741	    save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
742	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT);
743	}
744	OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch);
745    }
746}
747
748static void
749radeon_bios_output_connected(xf86OutputPtr output, Bool connected)
750{
751    ScrnInfoPtr	    pScrn = output->scrn;
752    RADEONInfoPtr info = RADEONPTR(pScrn);
753    RADEONOutputPrivatePtr radeon_output = output->driver_private;
754    unsigned char *RADEONMMIO = info->MMIO;
755    RADEONSavePtr save = info->ModeReg;
756
757    if (info->IsAtomBios) {
758	switch (radeon_output->active_device) {
759	case ATOM_DEVICE_TV1_SUPPORT:
760	    if (connected)
761		save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
762	    else {
763		save->bios_0_scratch &= ~ATOM_S0_TV1_MASK;
764		save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
765	    }
766	    break;
767	case ATOM_DEVICE_CV_SUPPORT:
768	    if (connected)
769		save->bios_3_scratch |= ATOM_S3_CV_ACTIVE;
770	    else {
771		save->bios_0_scratch &= ~ATOM_S0_CV_MASK;
772		save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
773	    }
774	    break;
775	case ATOM_DEVICE_LCD1_SUPPORT:
776	    if (connected) {
777		save->bios_0_scratch |= ATOM_S0_LCD1;
778		save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
779	    } else {
780		save->bios_0_scratch &= ~ATOM_S0_LCD1;
781		save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
782	    }
783	    break;
784	case ATOM_DEVICE_CRT1_SUPPORT:
785	    if (connected) {
786		save->bios_0_scratch |= ATOM_S0_CRT1_COLOR;
787		save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
788	    } else {
789		save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
790		save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
791	    }
792	    break;
793	case ATOM_DEVICE_CRT2_SUPPORT:
794	    if (connected) {
795		save->bios_0_scratch |= ATOM_S0_CRT2_COLOR;
796		save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
797	    } else {
798		save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
799		save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
800	    }
801	    break;
802	case ATOM_DEVICE_DFP1_SUPPORT:
803	    if (connected) {
804		save->bios_0_scratch |= ATOM_S0_DFP1;
805		save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
806	    } else {
807		save->bios_0_scratch &= ~ATOM_S0_DFP1;
808		save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
809	    }
810	    break;
811	case ATOM_DEVICE_DFP2_SUPPORT:
812	    if (connected) {
813		save->bios_0_scratch |= ATOM_S0_DFP2;
814		save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
815	    } else {
816		save->bios_0_scratch &= ~ATOM_S0_DFP2;
817		save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
818	    }
819	    break;
820	case ATOM_DEVICE_DFP3_SUPPORT:
821	    if (connected) {
822		save->bios_0_scratch |= ATOM_S0_DFP3;
823		save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
824	    } else {
825		save->bios_0_scratch &= ~ATOM_S0_DFP3;
826		save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
827	    }
828	    break;
829	case ATOM_DEVICE_DFP4_SUPPORT:
830	    if (connected) {
831		save->bios_0_scratch |= ATOM_S0_DFP4;
832		save->bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;
833	    } else {
834		save->bios_0_scratch &= ~ATOM_S0_DFP4;
835		save->bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;
836	    }
837	    break;
838	case ATOM_DEVICE_DFP5_SUPPORT:
839	    if (connected) {
840		save->bios_0_scratch |= ATOM_S0_DFP5;
841		save->bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;
842	    } else {
843		save->bios_0_scratch &= ~ATOM_S0_DFP5;
844		save->bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;
845	    }
846	    break;
847	}
848	if (info->ChipFamily >= CHIP_FAMILY_R600) {
849	    OUTREG(R600_BIOS_0_SCRATCH, save->bios_0_scratch);
850	    OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch);
851	} else {
852	    OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch);
853	    OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch);
854	}
855    } else {
856	switch (radeon_output->active_device) {
857	case ATOM_DEVICE_TV1_SUPPORT:
858	    if (connected) {
859		if (radeon_output->MonType == MT_STV)
860		    save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
861		else if (radeon_output->MonType == MT_CTV)
862		    save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP;
863		save->bios_5_scratch |= RADEON_TV1_ON;
864	    } else {
865		save->bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
866		save->bios_5_scratch &= ~RADEON_TV1_ON;
867	    }
868	    break;
869	case ATOM_DEVICE_LCD1_SUPPORT:
870	    if (connected) {
871		save->bios_4_scratch |= RADEON_LCD1_ATTACHED;
872		save->bios_5_scratch |= RADEON_LCD1_ON;
873	    } else {
874		save->bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
875		save->bios_5_scratch &= ~RADEON_LCD1_ON;
876	    }
877	    break;
878	case ATOM_DEVICE_CRT1_SUPPORT:
879	    if (connected) {
880		save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
881		save->bios_5_scratch |= RADEON_CRT1_ON;
882	    } else {
883		save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
884		save->bios_5_scratch &= ~RADEON_CRT1_ON;
885	    }
886	    break;
887	case ATOM_DEVICE_CRT2_SUPPORT:
888	    if (connected) {
889		save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
890		save->bios_5_scratch |= RADEON_CRT2_ON;
891	    } else {
892		save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
893		save->bios_5_scratch &= ~RADEON_CRT2_ON;
894	    }
895	    break;
896	case ATOM_DEVICE_DFP1_SUPPORT:
897	    if (connected) {
898		save->bios_4_scratch |= RADEON_DFP1_ATTACHED;
899		save->bios_5_scratch |= RADEON_DFP1_ON;
900	    } else {
901		save->bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
902		save->bios_5_scratch &= ~RADEON_DFP1_ON;
903	    }
904	    break;
905	case ATOM_DEVICE_DFP2_SUPPORT:
906	    if (connected) {
907		save->bios_4_scratch |= RADEON_DFP2_ATTACHED;
908		save->bios_5_scratch |= RADEON_DFP2_ON;
909	    } else {
910		save->bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
911		save->bios_5_scratch &= ~RADEON_DFP2_ON;
912	    }
913	    break;
914	}
915	OUTREG(RADEON_BIOS_4_SCRATCH, save->bios_4_scratch);
916	OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch);
917    }
918
919}
920
921static xf86OutputStatus
922radeon_detect(xf86OutputPtr output)
923{
924    ScrnInfoPtr	    pScrn = output->scrn;
925    RADEONInfoPtr info = RADEONPTR(pScrn);
926    RADEONOutputPrivatePtr radeon_output = output->driver_private;
927    Bool connected = TRUE;
928
929    radeon_output->MonType = MT_UNKNOWN;
930    radeon_bios_output_connected(output, FALSE);
931    radeon_output->MonType = radeon_ddc_connected(output);
932    if (!radeon_output->MonType) {
933	if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
934	    if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE))
935		radeon_output->MonType = MT_LCD;
936	    else
937#if defined(__powerpc__)
938		radeon_output->MonType = MT_LCD;
939#else
940	        radeon_output->MonType = RADEONDetectLidStatus(pScrn);
941#endif
942	} else {
943	    if (info->IsAtomBios)
944		radeon_output->MonType = atombios_dac_detect(output);
945	    else
946		radeon_output->MonType = legacy_dac_detect(output);
947	}
948    }
949
950    // if size is zero panel probably broken or not connected
951    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
952	radeon_encoder_ptr radeon_encoder = info->encoders[ATOM_DEVICE_LCD1_INDEX];
953	if (radeon_encoder) {
954	    radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
955	    if (lvds) {
956		if ((lvds->native_mode.PanelXRes == 0) || (lvds->native_mode.PanelYRes == 0))
957		    radeon_output->MonType = MT_NONE;
958	    }
959	}
960    }
961
962
963    if (output->MonInfo) {
964	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n",
965		   output->name);
966	xf86PrintEDID( output->MonInfo );
967    }
968
969    /* nothing connected, light up some defaults so the server comes up */
970    if (radeon_output->MonType == MT_NONE &&
971	info->first_load_no_devices) {
972	if (info->IsMobility) {
973	    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
974		radeon_output->MonType = MT_LCD;
975		info->first_load_no_devices = FALSE;
976		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LCD default\n");
977	    }
978	} else {
979	    if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
980		radeon_output->MonType = MT_CRT;
981		info->first_load_no_devices = FALSE;
982		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using CRT default\n");
983	    } else if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
984		radeon_output->MonType = MT_DFP;
985		info->first_load_no_devices = FALSE;
986		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DFP default\n");
987	    }
988	}
989    }
990
991    radeon_bios_output_connected(output, TRUE);
992
993    /* set montype so users can force outputs on even if detection fails */
994    if (radeon_output->MonType == MT_NONE) {
995	connected = FALSE;
996	switch (radeon_output->ConnectorType) {
997	case CONNECTOR_LVDS:
998	    radeon_output->MonType = MT_LCD;
999	    break;
1000	case CONNECTOR_DVI_D:
1001	case CONNECTOR_HDMI_TYPE_A:
1002	case CONNECTOR_HDMI_TYPE_B:
1003	    radeon_output->MonType = MT_DFP;
1004	    break;
1005	case CONNECTOR_VGA:
1006	case CONNECTOR_DVI_A:
1007	default:
1008	    radeon_output->MonType = MT_CRT;
1009	    break;
1010	case CONNECTOR_DVI_I:
1011	    if (radeon_output->DVIType == DVI_ANALOG)
1012		radeon_output->MonType = MT_CRT;
1013	    else if (radeon_output->DVIType == DVI_DIGITAL)
1014		radeon_output->MonType = MT_DFP;
1015	    break;
1016	case CONNECTOR_STV:
1017            radeon_output->MonType = MT_STV;
1018	    break;
1019	case CONNECTOR_CTV:
1020            radeon_output->MonType = MT_CTV;
1021	    break;
1022	case CONNECTOR_DIN:
1023            radeon_output->MonType = MT_CV;
1024	    break;
1025	case CONNECTOR_DISPLAY_PORT:
1026	    radeon_output->MonType = MT_DP;
1027	    break;
1028	}
1029    }
1030
1031    radeon_set_active_device(output);
1032
1033    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT))
1034	output->subpixel_order = SubPixelHorizontalRGB;
1035    else
1036	output->subpixel_order = SubPixelNone;
1037
1038    if (connected)
1039	return XF86OutputStatusConnected;
1040    else
1041	return XF86OutputStatusDisconnected;
1042}
1043
1044static DisplayModePtr
1045radeon_get_modes(xf86OutputPtr output)
1046{
1047  DisplayModePtr modes;
1048  modes = RADEONProbeOutputModes(output);
1049  return modes;
1050}
1051
1052static void
1053radeon_destroy (xf86OutputPtr output)
1054{
1055    if (output->driver_private)
1056        xfree(output->driver_private);
1057}
1058
1059static void
1060radeon_set_backlight_level(xf86OutputPtr output, int level)
1061{
1062#if 0
1063    ScrnInfoPtr pScrn = output->scrn;
1064    RADEONInfoPtr info = RADEONPTR(pScrn);
1065    unsigned char * RADEONMMIO = info->MMIO;
1066    uint32_t lvds_gen_cntl;
1067
1068    lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
1069    lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
1070    lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK;
1071    lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK;
1072    //usleep (radeon_output->PanelPwrDly * 1000);
1073    OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
1074    lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN;
1075    //usleep (radeon_output->PanelPwrDly * 1000);
1076    OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
1077#endif
1078}
1079
1080static Atom backlight_atom;
1081static Atom tmds_pll_atom;
1082static Atom rmx_atom;
1083static Atom monitor_type_atom;
1084static Atom load_detection_atom;
1085static Atom coherent_mode_atom;
1086static Atom tv_hsize_atom;
1087static Atom tv_hpos_atom;
1088static Atom tv_vpos_atom;
1089static Atom tv_std_atom;
1090#define RADEON_MAX_BACKLIGHT_LEVEL 255
1091
1092static void
1093radeon_create_resources(xf86OutputPtr output)
1094{
1095    ScrnInfoPtr pScrn = output->scrn;
1096    RADEONInfoPtr info = RADEONPTR(pScrn);
1097    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1098    INT32 range[2];
1099    int data, err;
1100    const char *s;
1101
1102#if 0
1103    /* backlight control */
1104    if (radeon_output->type == OUTPUT_LVDS) {
1105	backlight_atom = MAKE_ATOM("backlight");
1106
1107	range[0] = 0;
1108	range[1] = RADEON_MAX_BACKLIGHT_LEVEL;
1109	err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
1110					FALSE, TRUE, FALSE, 2, range);
1111	if (err != 0) {
1112	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1113		       "RRConfigureOutputProperty error, %d\n", err);
1114	}
1115	/* Set the current value of the backlight property */
1116	//data = (info->SavedReg->lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT;
1117	data = RADEON_MAX_BACKLIGHT_LEVEL;
1118	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
1119				     XA_INTEGER, 32, PropModeReplace, 1, &data,
1120				     FALSE, TRUE);
1121	if (err != 0) {
1122	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1123		       "RRChangeOutputProperty error, %d\n", err);
1124	}
1125    }
1126#endif
1127
1128    if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT | ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
1129	load_detection_atom = MAKE_ATOM("load_detection");
1130
1131	range[0] = 0; /* off */
1132	range[1] = 1; /* on */
1133	err = RRConfigureOutputProperty(output->randr_output, load_detection_atom,
1134					FALSE, TRUE, FALSE, 2, range);
1135	if (err != 0) {
1136	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1137		       "RRConfigureOutputProperty error, %d\n", err);
1138	}
1139
1140	if (radeon_output->load_detection)
1141	    data = 1;
1142	else
1143	    data = 0;
1144
1145	err = RRChangeOutputProperty(output->randr_output, load_detection_atom,
1146				     XA_INTEGER, 32, PropModeReplace, 1, &data,
1147				     FALSE, TRUE);
1148	if (err != 0) {
1149	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1150		       "RRChangeOutputProperty error, %d\n", err);
1151	}
1152    }
1153
1154    if (IS_AVIVO_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) {
1155	coherent_mode_atom = MAKE_ATOM("coherent_mode");
1156
1157	range[0] = 0; /* off */
1158	range[1] = 1; /* on */
1159	err = RRConfigureOutputProperty(output->randr_output, coherent_mode_atom,
1160					FALSE, TRUE, FALSE, 2, range);
1161	if (err != 0) {
1162	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1163		       "RRConfigureOutputProperty error, %d\n", err);
1164	}
1165
1166	data = 1; /* coherent mode on by default */
1167
1168	err = RRChangeOutputProperty(output->randr_output, coherent_mode_atom,
1169				     XA_INTEGER, 32, PropModeReplace, 1, &data,
1170				     FALSE, TRUE);
1171	if (err != 0) {
1172	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1173		       "RRChangeOutputProperty error, %d\n", err);
1174	}
1175    }
1176
1177    if ((!IS_AVIVO_VARIANT) && (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT))) {
1178	tmds_pll_atom = MAKE_ATOM("tmds_pll");
1179
1180	err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
1181					FALSE, FALSE, FALSE, 0, NULL);
1182	if (err != 0) {
1183	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1184		       "RRConfigureOutputProperty error, %d\n", err);
1185	}
1186	/* Set the current value of the property */
1187#if defined(__powerpc__)
1188	s = "driver";
1189#else
1190	s = "bios";
1191#endif
1192	if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_TMDS_PLL, FALSE)) {
1193	    s = "driver";
1194	}
1195
1196	err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom,
1197				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
1198				     FALSE, FALSE);
1199	if (err != 0) {
1200	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1201		       "RRChangeOutputProperty error, %d\n", err);
1202	}
1203
1204    }
1205
1206    /* RMX control - fullscreen, centered, keep ratio, off */
1207    /* actually more of a crtc property as only crtc1 has rmx */
1208    if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
1209	rmx_atom = MAKE_ATOM("scaler");
1210
1211	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
1212					FALSE, FALSE, FALSE, 0, NULL);
1213	if (err != 0) {
1214	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1215		       "RRConfigureOutputProperty error, %d\n", err);
1216	}
1217	/* Set the current value of the property */
1218	switch (radeon_output->rmx_type) {
1219	case RMX_OFF:
1220	default:
1221	    s = "off";
1222	    break;
1223	case RMX_FULL:
1224	    s = "full";
1225	    break;
1226	case RMX_CENTER:
1227	    s = "center";
1228	    break;
1229	case RMX_ASPECT:
1230	    s = "aspect";
1231	    break;
1232	}
1233	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
1234				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
1235				     FALSE, FALSE);
1236	if (err != 0) {
1237	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1238		       "RRChangeOutputProperty error, %d\n", err);
1239	}
1240    }
1241
1242    /* force auto/analog/digital for DVI-I ports */
1243    if ((radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) &&
1244	(radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))){
1245	monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
1246
1247	err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
1248					FALSE, FALSE, FALSE, 0, NULL);
1249	if (err != 0) {
1250	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1251		       "RRConfigureOutputProperty error, %d\n", err);
1252	}
1253	/* Set the current value of the backlight property */
1254	s = "auto";
1255	err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
1256				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
1257				     FALSE, FALSE);
1258	if (err != 0) {
1259	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1260		       "RRChangeOutputProperty error, %d\n", err);
1261	}
1262    }
1263
1264    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) {
1265	radeon_tvout_ptr tvout = &radeon_output->tvout;
1266	if (!IS_AVIVO_VARIANT) {
1267	    tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
1268
1269	    range[0] = -MAX_H_SIZE;
1270	    range[1] = MAX_H_SIZE;
1271	    err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom,
1272					    FALSE, TRUE, FALSE, 2, range);
1273	    if (err != 0) {
1274		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1275			   "RRConfigureOutputProperty error, %d\n", err);
1276	    }
1277	    data = 0;
1278	    err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom,
1279					 XA_INTEGER, 32, PropModeReplace, 1, &data,
1280					 FALSE, TRUE);
1281	    if (err != 0) {
1282		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1283			   "RRChangeOutputProperty error, %d\n", err);
1284	    }
1285
1286	    tv_hpos_atom = MAKE_ATOM("tv_horizontal_position");
1287
1288	    range[0] = -MAX_H_POSITION;
1289	    range[1] = MAX_H_POSITION;
1290	    err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom,
1291					    FALSE, TRUE, FALSE, 2, range);
1292	    if (err != 0) {
1293		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1294			   "RRConfigureOutputProperty error, %d\n", err);
1295	    }
1296	    data = 0;
1297	    err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom,
1298					 XA_INTEGER, 32, PropModeReplace, 1, &data,
1299					 FALSE, TRUE);
1300	    if (err != 0) {
1301		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1302			   "RRChangeOutputProperty error, %d\n", err);
1303	    }
1304
1305	    tv_vpos_atom = MAKE_ATOM("tv_vertical_position");
1306
1307	    range[0] = -MAX_V_POSITION;
1308	    range[1] = MAX_V_POSITION;
1309	    err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom,
1310					    FALSE, TRUE, FALSE, 2, range);
1311	    if (err != 0) {
1312		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1313			   "RRConfigureOutputProperty error, %d\n", err);
1314	    }
1315	    data = 0;
1316	    err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom,
1317					 XA_INTEGER, 32, PropModeReplace, 1, &data,
1318					 FALSE, TRUE);
1319	    if (err != 0) {
1320		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1321			   "RRChangeOutputProperty error, %d\n", err);
1322	    }
1323	}
1324
1325	tv_std_atom = MAKE_ATOM("tv_standard");
1326
1327	err = RRConfigureOutputProperty(output->randr_output, tv_std_atom,
1328					FALSE, FALSE, FALSE, 0, NULL);
1329	if (err != 0) {
1330	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1331		       "RRConfigureOutputProperty error, %d\n", err);
1332	}
1333
1334	/* Set the current value of the property */
1335	switch (tvout->tvStd) {
1336	case TV_STD_PAL:
1337	    s = "pal";
1338	    break;
1339	case TV_STD_PAL_M:
1340	    s = "pal-m";
1341	    break;
1342	case TV_STD_PAL_60:
1343	    s = "pal-60";
1344	    break;
1345	case TV_STD_NTSC_J:
1346	    s = "ntsc-j";
1347	    break;
1348	case TV_STD_SCART_PAL:
1349	    s = "scart-pal";
1350	    break;
1351	case TV_STD_NTSC:
1352	default:
1353	    s = "ntsc";
1354	    break;
1355	}
1356
1357	err = RRChangeOutputProperty(output->randr_output, tv_std_atom,
1358				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
1359				     FALSE, FALSE);
1360	if (err != 0) {
1361	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1362		       "RRChangeOutputProperty error, %d\n", err);
1363	}
1364    }
1365}
1366
1367static Bool
1368radeon_set_mode_for_property(xf86OutputPtr output)
1369{
1370    ScrnInfoPtr pScrn = output->scrn;
1371
1372    if (output->crtc) {
1373	xf86CrtcPtr crtc = output->crtc;
1374
1375	if (crtc->enabled) {
1376	    if (!xf86CrtcSetMode(crtc, &crtc->desiredMode, crtc->desiredRotation,
1377				 crtc->desiredX, crtc->desiredY)) {
1378		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1379			   "Failed to set mode after propery change!\n");
1380		return FALSE;
1381	    }
1382	}
1383    }
1384    return TRUE;
1385}
1386
1387static Bool
1388radeon_set_property(xf86OutputPtr output, Atom property,
1389		       RRPropertyValuePtr value)
1390{
1391    RADEONInfoPtr info = RADEONPTR(output->scrn);
1392    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1393    INT32 val;
1394
1395
1396    if (property == backlight_atom) {
1397	if (value->type != XA_INTEGER ||
1398	    value->format != 32 ||
1399	    value->size != 1) {
1400	    return FALSE;
1401	}
1402
1403	val = *(INT32 *)value->data;
1404	if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL)
1405	    return FALSE;
1406
1407#if defined(__powerpc__)
1408	val = RADEON_MAX_BACKLIGHT_LEVEL - val;
1409#endif
1410
1411	radeon_set_backlight_level(output, val);
1412
1413    } else if (property == load_detection_atom) {
1414	if (value->type != XA_INTEGER ||
1415	    value->format != 32 ||
1416	    value->size != 1) {
1417	    return FALSE;
1418	}
1419
1420	val = *(INT32 *)value->data;
1421	if (val < 0 || val > 1)
1422	    return FALSE;
1423
1424	radeon_output->load_detection = val;
1425
1426    } else if (property == coherent_mode_atom) {
1427	Bool coherent_mode = radeon_output->coherent_mode;
1428
1429	if (value->type != XA_INTEGER ||
1430	    value->format != 32 ||
1431	    value->size != 1) {
1432	    return FALSE;
1433	}
1434
1435	val = *(INT32 *)value->data;
1436	if (val < 0 || val > 1)
1437	    return FALSE;
1438
1439	radeon_output->coherent_mode = val;
1440	if (!radeon_set_mode_for_property(output)) {
1441	    radeon_output->coherent_mode = coherent_mode;
1442	    (void)radeon_set_mode_for_property(output);
1443	    return FALSE;
1444	}
1445
1446    } else if (property == rmx_atom) {
1447	const char *s;
1448	RADEONRMXType rmx = radeon_output->rmx_type;
1449
1450	if (value->type != XA_STRING || value->format != 8)
1451	    return FALSE;
1452	s = (char*)value->data;
1453	if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) {
1454	    radeon_output->rmx_type = RMX_FULL;
1455	} else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) {
1456	    radeon_output->rmx_type = RMX_CENTER;
1457	} else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) {
1458	    if (IS_AVIVO_VARIANT)
1459		radeon_output->rmx_type = RMX_ASPECT;
1460	    else
1461		return FALSE;
1462	} else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) {
1463	    radeon_output->rmx_type = RMX_OFF;
1464	} else
1465	    return FALSE;
1466
1467	if (!radeon_set_mode_for_property(output)) {
1468	    radeon_output->rmx_type = rmx;
1469	    (void)radeon_set_mode_for_property(output);
1470	    return FALSE;
1471	}
1472    } else if (property == tmds_pll_atom) {
1473	radeon_tmds_ptr tmds = NULL;
1474	const char *s;
1475
1476	if (info->encoders[ATOM_DEVICE_DFP1_INDEX] && info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv)
1477	    tmds = (radeon_tmds_ptr)info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv;
1478	else
1479	    return FALSE;
1480
1481	if (value->type != XA_STRING || value->format != 8)
1482	    return FALSE;
1483	s = (char*)value->data;
1484	if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) {
1485	    if (!RADEONGetTMDSInfoFromBIOS(output->scrn, tmds))
1486		RADEONGetTMDSInfoFromTable(output->scrn, tmds);
1487	} else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver")))
1488	    RADEONGetTMDSInfoFromTable(output->scrn, tmds);
1489	else
1490	    return FALSE;
1491
1492	return radeon_set_mode_for_property(output);
1493    } else if (property == monitor_type_atom) {
1494	const char *s;
1495	if (value->type != XA_STRING || value->format != 8)
1496	    return FALSE;
1497	s = (char*)value->data;
1498	if (value->size == strlen("auto") && !strncmp("auto", s, strlen("auto"))) {
1499	    radeon_output->DVIType = DVI_AUTO;
1500	    return TRUE;
1501	} else if (value->size == strlen("analog") && !strncmp("analog", s, strlen("analog"))) {
1502	    radeon_output->DVIType = DVI_ANALOG;
1503	    return TRUE;
1504	} else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) {
1505	    radeon_output->DVIType = DVI_DIGITAL;
1506	    return TRUE;
1507	} else
1508	    return FALSE;
1509    } else if (property == tv_hsize_atom) {
1510	radeon_tvout_ptr tvout = &radeon_output->tvout;
1511	if (value->type != XA_INTEGER ||
1512	    value->format != 32 ||
1513	    value->size != 1) {
1514	    return FALSE;
1515	}
1516
1517	val = *(INT32 *)value->data;
1518	if (val < -MAX_H_SIZE || val > MAX_H_SIZE)
1519	    return FALSE;
1520
1521	tvout->hSize = val;
1522	if (tvout->tv_on && !IS_AVIVO_VARIANT)
1523	    RADEONUpdateHVPosition(output, &output->crtc->mode);
1524
1525    } else if (property == tv_hpos_atom) {
1526	radeon_tvout_ptr tvout = &radeon_output->tvout;
1527	if (value->type != XA_INTEGER ||
1528	    value->format != 32 ||
1529	    value->size != 1) {
1530	    return FALSE;
1531	}
1532
1533	val = *(INT32 *)value->data;
1534	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
1535	    return FALSE;
1536
1537	tvout->hPos = val;
1538	if (tvout->tv_on && !IS_AVIVO_VARIANT)
1539	    RADEONUpdateHVPosition(output, &output->crtc->mode);
1540
1541    } else if (property == tv_vpos_atom) {
1542	radeon_tvout_ptr tvout = &radeon_output->tvout;
1543	if (value->type != XA_INTEGER ||
1544	    value->format != 32 ||
1545	    value->size != 1) {
1546	    return FALSE;
1547	}
1548
1549	val = *(INT32 *)value->data;
1550	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
1551	    return FALSE;
1552
1553	tvout->vPos = val;
1554	if (tvout->tv_on && !IS_AVIVO_VARIANT)
1555	    RADEONUpdateHVPosition(output, &output->crtc->mode);
1556
1557    } else if (property == tv_std_atom) {
1558	const char *s;
1559	radeon_tvout_ptr tvout = &radeon_output->tvout;
1560	TVStd std = tvout->tvStd;
1561
1562	if (value->type != XA_STRING || value->format != 8)
1563	    return FALSE;
1564	s = (char*)value->data;
1565	if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) {
1566	    tvout->tvStd = TV_STD_NTSC;
1567	} else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) {
1568	    tvout->tvStd = TV_STD_PAL;
1569	} else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) {
1570	    tvout->tvStd = TV_STD_PAL_M;
1571	} else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) {
1572	    tvout->tvStd = TV_STD_PAL_60;
1573	} else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) {
1574	    tvout->tvStd = TV_STD_NTSC_J;
1575	} else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) {
1576	    tvout->tvStd = TV_STD_SCART_PAL;
1577	} else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) {
1578	    tvout->tvStd = TV_STD_PAL_CN;
1579	} else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) {
1580	    tvout->tvStd = TV_STD_SECAM;
1581	} else
1582	    return FALSE;
1583
1584	if (!radeon_set_mode_for_property(output)) {
1585	    tvout->tvStd = std;
1586	    (void)radeon_set_mode_for_property(output);
1587	    return FALSE;
1588	}
1589    }
1590
1591    return TRUE;
1592}
1593
1594static const xf86OutputFuncsRec radeon_output_funcs = {
1595    .create_resources = radeon_create_resources,
1596    .dpms = radeon_dpms,
1597    .save = radeon_save,
1598    .restore = radeon_restore,
1599    .mode_valid = radeon_mode_valid,
1600    .mode_fixup = radeon_mode_fixup,
1601    .prepare = radeon_mode_prepare,
1602    .mode_set = radeon_mode_set,
1603    .commit = radeon_mode_commit,
1604    .detect = radeon_detect,
1605    .get_modes = radeon_get_modes,
1606    .set_property = radeon_set_property,
1607    .destroy = radeon_destroy
1608};
1609
1610Bool
1611RADEONI2CDoLock(xf86OutputPtr output, int lock_state)
1612{
1613    ScrnInfoPtr pScrn = output->scrn;
1614    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1615    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1616    RADEONI2CBusPtr pRADEONI2CBus = radeon_output->pI2CBus->DriverPrivate.ptr;
1617    unsigned char *RADEONMMIO = info->MMIO;
1618    uint32_t temp;
1619
1620    if (lock_state) {
1621	temp = INREG(pRADEONI2CBus->a_clk_reg);
1622	temp &= ~(pRADEONI2CBus->a_clk_mask);
1623	OUTREG(pRADEONI2CBus->a_clk_reg, temp);
1624
1625	temp = INREG(pRADEONI2CBus->a_data_reg);
1626	temp &= ~(pRADEONI2CBus->a_data_mask);
1627	OUTREG(pRADEONI2CBus->a_data_reg, temp);
1628    }
1629
1630    temp = INREG(pRADEONI2CBus->mask_clk_reg);
1631    if (lock_state)
1632	temp |= (pRADEONI2CBus->mask_clk_mask);
1633    else
1634	temp &= ~(pRADEONI2CBus->mask_clk_mask);
1635    OUTREG(pRADEONI2CBus->mask_clk_reg, temp);
1636    temp = INREG(pRADEONI2CBus->mask_clk_reg);
1637
1638    temp = INREG(pRADEONI2CBus->mask_data_reg);
1639    if (lock_state)
1640	temp |= (pRADEONI2CBus->mask_data_mask);
1641    else
1642	temp &= ~(pRADEONI2CBus->mask_data_mask);
1643    OUTREG(pRADEONI2CBus->mask_data_reg, temp);
1644    temp = INREG(pRADEONI2CBus->mask_data_reg);
1645
1646    return TRUE;
1647}
1648
1649static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
1650{
1651    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
1652    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1653    unsigned long  val;
1654    unsigned char *RADEONMMIO = info->MMIO;
1655    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
1656
1657    /* Get the result */
1658    val = INREG(pRADEONI2CBus->get_clk_reg);
1659    *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0;
1660    val = INREG(pRADEONI2CBus->get_data_reg);
1661    *data  = (val & pRADEONI2CBus->get_data_mask) != 0;
1662
1663}
1664
1665static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
1666{
1667    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
1668    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1669    unsigned long  val;
1670    unsigned char *RADEONMMIO = info->MMIO;
1671    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
1672
1673    val = INREG(pRADEONI2CBus->put_clk_reg) & (uint32_t)~(pRADEONI2CBus->put_clk_mask);
1674    val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask);
1675    OUTREG(pRADEONI2CBus->put_clk_reg, val);
1676    /* read back to improve reliability on some cards. */
1677    val = INREG(pRADEONI2CBus->put_clk_reg);
1678
1679    val = INREG(pRADEONI2CBus->put_data_reg) & (uint32_t)~(pRADEONI2CBus->put_data_mask);
1680    val |= (data ? 0:pRADEONI2CBus->put_data_mask);
1681    OUTREG(pRADEONI2CBus->put_data_reg, val);
1682    /* read back to improve reliability on some cards. */
1683    val = INREG(pRADEONI2CBus->put_data_reg);
1684
1685}
1686
1687Bool
1688RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus)
1689{
1690    I2CBusPtr pI2CBus;
1691
1692    pI2CBus = xf86CreateI2CBusRec();
1693    if (!pI2CBus) return FALSE;
1694
1695    pI2CBus->BusName    = name;
1696    pI2CBus->scrnIndex  = pScrn->scrnIndex;
1697    pI2CBus->I2CPutBits = RADEONI2CPutBits;
1698    pI2CBus->I2CGetBits = RADEONI2CGetBits;
1699    pI2CBus->AcknTimeout = 5;
1700
1701    pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus;
1702
1703    if (!xf86I2CBusInit(pI2CBus))
1704	return FALSE;
1705
1706    *bus_ptr = pI2CBus;
1707    return TRUE;
1708}
1709
1710RADEONI2CBusRec
1711legacy_setup_i2c_bus(int ddc_line)
1712{
1713    RADEONI2CBusRec i2c;
1714
1715    i2c.hw_line = 0;
1716    i2c.hw_capable = FALSE;
1717    i2c.mask_clk_mask = RADEON_GPIO_EN_1;
1718    i2c.mask_data_mask = RADEON_GPIO_EN_0;
1719    i2c.a_clk_mask = RADEON_GPIO_A_1;
1720    i2c.a_data_mask = RADEON_GPIO_A_0;
1721    i2c.put_clk_mask = RADEON_GPIO_EN_1;
1722    i2c.put_data_mask = RADEON_GPIO_EN_0;
1723    i2c.get_clk_mask = RADEON_GPIO_Y_1;
1724    i2c.get_data_mask = RADEON_GPIO_Y_0;
1725    if ((ddc_line == RADEON_LCD_GPIO_MASK) ||
1726	(ddc_line == RADEON_MDGPIO_EN_REG)) {
1727	i2c.mask_clk_reg = ddc_line;
1728	i2c.mask_data_reg = ddc_line;
1729	i2c.a_clk_reg = ddc_line;
1730	i2c.a_data_reg = ddc_line;
1731	i2c.put_clk_reg = ddc_line;
1732	i2c.put_data_reg = ddc_line;
1733	i2c.get_clk_reg = ddc_line + 4;
1734	i2c.get_data_reg = ddc_line + 4;
1735    } else {
1736	i2c.mask_clk_reg = ddc_line;
1737	i2c.mask_data_reg = ddc_line;
1738	i2c.a_clk_reg = ddc_line;
1739	i2c.a_data_reg = ddc_line;
1740	i2c.put_clk_reg = ddc_line;
1741	i2c.put_data_reg = ddc_line;
1742	i2c.get_clk_reg = ddc_line;
1743	i2c.get_data_reg = ddc_line;
1744    }
1745
1746    if (ddc_line)
1747	i2c.valid = TRUE;
1748    else
1749	i2c.valid = FALSE;
1750
1751    return i2c;
1752}
1753
1754RADEONI2CBusRec
1755atom_setup_i2c_bus(int ddc_line)
1756{
1757    RADEONI2CBusRec i2c;
1758
1759    i2c.hw_line = 0;
1760    i2c.hw_capable = FALSE;
1761    if (ddc_line == AVIVO_GPIO_0) {
1762	i2c.put_clk_mask = (1 << 19);
1763	i2c.put_data_mask = (1 << 18);
1764	i2c.get_clk_mask = (1 << 19);
1765	i2c.get_data_mask = (1 << 18);
1766	i2c.mask_clk_mask = (1 << 19);
1767	i2c.mask_data_mask = (1 << 18);
1768	i2c.a_clk_mask = (1 << 19);
1769	i2c.a_data_mask = (1 << 18);
1770    } else {
1771	i2c.put_clk_mask = (1 << 0);
1772	i2c.put_data_mask = (1 << 8);
1773	i2c.get_clk_mask = (1 << 0);
1774	i2c.get_data_mask = (1 << 8);
1775	i2c.mask_clk_mask = (1 << 0);
1776	i2c.mask_data_mask = (1 << 8);
1777	i2c.a_clk_mask = (1 << 0);
1778	i2c.a_data_mask = (1 << 8);
1779    }
1780    i2c.mask_clk_reg = ddc_line;
1781    i2c.mask_data_reg = ddc_line;
1782    i2c.a_clk_reg = ddc_line + 0x4;
1783    i2c.a_data_reg = ddc_line + 0x4;
1784    i2c.put_clk_reg = ddc_line + 0x8;
1785    i2c.put_data_reg = ddc_line + 0x8;
1786    i2c.get_clk_reg = ddc_line + 0xc;
1787    i2c.get_data_reg = ddc_line + 0xc;
1788    if (ddc_line)
1789	i2c.valid = TRUE;
1790    else
1791	i2c.valid = FALSE;
1792
1793    return i2c;
1794}
1795
1796static void
1797RADEONGetTVInfo(xf86OutputPtr output)
1798{
1799    ScrnInfoPtr pScrn = output->scrn;
1800    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1801    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1802    radeon_tvout_ptr tvout = &radeon_output->tvout;
1803    char *optstr;
1804
1805    tvout->hPos = 0;
1806    tvout->vPos = 0;
1807    tvout->hSize = 0;
1808    tvout->tv_on = FALSE;
1809
1810    if (!RADEONGetTVInfoFromBIOS(output)) {
1811	/* set some reasonable defaults */
1812	tvout->default_tvStd = TV_STD_NTSC;
1813	tvout->tvStd = TV_STD_NTSC;
1814	tvout->TVRefClk = 27.000000000;
1815	tvout->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
1816    }
1817
1818    optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD);
1819    if (optstr) {
1820	if (!strncmp("ntsc", optstr, strlen("ntsc")))
1821	    tvout->tvStd = TV_STD_NTSC;
1822	else if (!strncmp("pal", optstr, strlen("pal")))
1823	    tvout->tvStd = TV_STD_PAL;
1824	else if (!strncmp("pal-m", optstr, strlen("pal-m")))
1825	    tvout->tvStd = TV_STD_PAL_M;
1826	else if (!strncmp("pal-60", optstr, strlen("pal-60")))
1827	    tvout->tvStd = TV_STD_PAL_60;
1828	else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j")))
1829	    tvout->tvStd = TV_STD_NTSC_J;
1830	else if (!strncmp("scart-pal", optstr, strlen("scart-pal")))
1831	    tvout->tvStd = TV_STD_SCART_PAL;
1832	else {
1833	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr);
1834	}
1835    }
1836
1837}
1838
1839void RADEONInitConnector(xf86OutputPtr output)
1840{
1841    ScrnInfoPtr	    pScrn = output->scrn;
1842    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1843    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1844
1845    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))
1846	radeon_output->rmx_type = RMX_FULL;
1847    else
1848	radeon_output->rmx_type = RMX_OFF;
1849
1850    /* dce 3.2 chips have problems with low dot clocks, so use the scaler */
1851    if (IS_DCE32_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)))
1852	radeon_output->rmx_type = RMX_FULL;
1853
1854    if (!IS_AVIVO_VARIANT) {
1855	if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) {
1856	    if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
1857		radeon_output->load_detection = 1;
1858	}
1859    }
1860
1861    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
1862	RADEONGetTVInfo(output);
1863
1864    if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))
1865	radeon_output->coherent_mode = TRUE;
1866
1867    if (radeon_output->ddc_i2c.valid)
1868	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, output->name, &radeon_output->ddc_i2c);
1869
1870}
1871
1872#if defined(__powerpc__)
1873static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
1874{
1875    RADEONInfoPtr info       = RADEONPTR(pScrn);
1876
1877
1878    switch (info->MacModel) {
1879    case RADEON_MAC_IBOOK:
1880	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1881	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
1882	info->BiosConnector[0].valid = TRUE;
1883	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
1884	if (!radeon_add_encoder(pScrn,
1885				radeon_get_encoder_id_from_supported_device(pScrn,
1886									    ATOM_DEVICE_LCD1_SUPPORT,
1887									    0),
1888				ATOM_DEVICE_LCD1_SUPPORT))
1889	    return FALSE;
1890
1891	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
1892	info->BiosConnector[1].load_detection = FALSE;
1893	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
1894	info->BiosConnector[1].valid = TRUE;
1895	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
1896	if (!radeon_add_encoder(pScrn,
1897				radeon_get_encoder_id_from_supported_device(pScrn,
1898									    ATOM_DEVICE_CRT2_SUPPORT,
1899									    2),
1900				ATOM_DEVICE_CRT2_SUPPORT))
1901	    return FALSE;
1902
1903	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
1904	info->BiosConnector[2].load_detection = FALSE;
1905	info->BiosConnector[2].ddc_i2c.valid = FALSE;
1906	info->BiosConnector[2].valid = TRUE;
1907	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
1908	if (!radeon_add_encoder(pScrn,
1909				radeon_get_encoder_id_from_supported_device(pScrn,
1910									    ATOM_DEVICE_TV1_SUPPORT,
1911									    2),
1912				ATOM_DEVICE_TV1_SUPPORT))
1913	    return FALSE;
1914	return TRUE;
1915    case RADEON_MAC_POWERBOOK_EXTERNAL:
1916	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1917	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
1918	info->BiosConnector[0].valid = TRUE;
1919	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
1920	if (!radeon_add_encoder(pScrn,
1921				radeon_get_encoder_id_from_supported_device(pScrn,
1922									    ATOM_DEVICE_LCD1_SUPPORT,
1923									    0),
1924				ATOM_DEVICE_LCD1_SUPPORT))
1925	    return FALSE;
1926
1927	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
1928	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
1929	info->BiosConnector[1].valid = TRUE;
1930	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
1931	if (!radeon_add_encoder(pScrn,
1932				radeon_get_encoder_id_from_supported_device(pScrn,
1933									    ATOM_DEVICE_CRT1_SUPPORT,
1934									    1),
1935				ATOM_DEVICE_CRT1_SUPPORT))
1936	    return FALSE;
1937	if (!radeon_add_encoder(pScrn,
1938				radeon_get_encoder_id_from_supported_device(pScrn,
1939									    ATOM_DEVICE_DFP2_SUPPORT,
1940									    0),
1941				ATOM_DEVICE_DFP2_SUPPORT))
1942	    return FALSE;
1943
1944	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
1945	info->BiosConnector[2].load_detection = FALSE;
1946	info->BiosConnector[2].ddc_i2c.valid = FALSE;
1947	info->BiosConnector[2].valid = TRUE;
1948	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
1949	if (!radeon_add_encoder(pScrn,
1950				radeon_get_encoder_id_from_supported_device(pScrn,
1951									    ATOM_DEVICE_TV1_SUPPORT,
1952									    2),
1953				ATOM_DEVICE_TV1_SUPPORT))
1954	    return FALSE;
1955	return TRUE;
1956    case RADEON_MAC_POWERBOOK_INTERNAL:
1957	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1958	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
1959	info->BiosConnector[0].valid = TRUE;
1960	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
1961	if (!radeon_add_encoder(pScrn,
1962				radeon_get_encoder_id_from_supported_device(pScrn,
1963									    ATOM_DEVICE_LCD1_SUPPORT,
1964									    0),
1965				ATOM_DEVICE_LCD1_SUPPORT))
1966	    return FALSE;
1967
1968	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
1969	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
1970	info->BiosConnector[1].valid = TRUE;
1971	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
1972	if (!radeon_add_encoder(pScrn,
1973				radeon_get_encoder_id_from_supported_device(pScrn,
1974									    ATOM_DEVICE_CRT1_SUPPORT,
1975									    1),
1976				ATOM_DEVICE_CRT1_SUPPORT))
1977	    return FALSE;
1978	if (!radeon_add_encoder(pScrn,
1979				radeon_get_encoder_id_from_supported_device(pScrn,
1980									    ATOM_DEVICE_DFP1_SUPPORT,
1981									    0),
1982				ATOM_DEVICE_DFP1_SUPPORT))
1983	    return FALSE;
1984
1985	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
1986	info->BiosConnector[2].load_detection = FALSE;
1987	info->BiosConnector[2].ddc_i2c.valid = FALSE;
1988	info->BiosConnector[2].valid = TRUE;
1989	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
1990	if (!radeon_add_encoder(pScrn,
1991				radeon_get_encoder_id_from_supported_device(pScrn,
1992									    ATOM_DEVICE_TV1_SUPPORT,
1993									    2),
1994				ATOM_DEVICE_TV1_SUPPORT))
1995	    return FALSE;
1996	return TRUE;
1997    case RADEON_MAC_POWERBOOK_VGA:
1998	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1999	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
2000	info->BiosConnector[0].valid = TRUE;
2001	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
2002	if (!radeon_add_encoder(pScrn,
2003				radeon_get_encoder_id_from_supported_device(pScrn,
2004									    ATOM_DEVICE_LCD1_SUPPORT,
2005									    0),
2006				ATOM_DEVICE_LCD1_SUPPORT))
2007	    return FALSE;
2008
2009	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2010	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2011	info->BiosConnector[1].valid = TRUE;
2012	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
2013	if (!radeon_add_encoder(pScrn,
2014				radeon_get_encoder_id_from_supported_device(pScrn,
2015									    ATOM_DEVICE_CRT1_SUPPORT,
2016									    1),
2017				ATOM_DEVICE_CRT1_SUPPORT))
2018	    return FALSE;
2019
2020	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
2021	info->BiosConnector[2].load_detection = FALSE;
2022	info->BiosConnector[2].ddc_i2c.valid = FALSE;
2023	info->BiosConnector[2].valid = TRUE;
2024	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
2025	if (!radeon_add_encoder(pScrn,
2026				radeon_get_encoder_id_from_supported_device(pScrn,
2027									    ATOM_DEVICE_TV1_SUPPORT,
2028									    2),
2029				ATOM_DEVICE_TV1_SUPPORT))
2030	    return FALSE;
2031	return TRUE;
2032    case RADEON_MAC_MINI_EXTERNAL:
2033	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
2034	info->BiosConnector[0].load_detection = FALSE;
2035	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
2036	info->BiosConnector[0].valid = TRUE;
2037	info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
2038	if (!radeon_add_encoder(pScrn,
2039				radeon_get_encoder_id_from_supported_device(pScrn,
2040									    ATOM_DEVICE_CRT2_SUPPORT,
2041									    2),
2042				ATOM_DEVICE_CRT2_SUPPORT))
2043	    return FALSE;
2044	if (!radeon_add_encoder(pScrn,
2045				radeon_get_encoder_id_from_supported_device(pScrn,
2046									    ATOM_DEVICE_DFP2_SUPPORT,
2047									    0),
2048				ATOM_DEVICE_DFP2_SUPPORT))
2049	    return FALSE;
2050
2051	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
2052	info->BiosConnector[1].load_detection = FALSE;
2053	info->BiosConnector[1].ddc_i2c.valid = FALSE;
2054	info->BiosConnector[1].valid = TRUE;
2055	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
2056	if (!radeon_add_encoder(pScrn,
2057				radeon_get_encoder_id_from_supported_device(pScrn,
2058									    ATOM_DEVICE_TV1_SUPPORT,
2059									    2),
2060				ATOM_DEVICE_TV1_SUPPORT))
2061	    return FALSE;
2062	return TRUE;
2063    case RADEON_MAC_MINI_INTERNAL:
2064	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
2065	info->BiosConnector[0].load_detection = FALSE;
2066	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
2067	info->BiosConnector[0].valid = TRUE;
2068	info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
2069	if (!radeon_add_encoder(pScrn,
2070				radeon_get_encoder_id_from_supported_device(pScrn,
2071									    ATOM_DEVICE_CRT2_SUPPORT,
2072									    2),
2073				ATOM_DEVICE_CRT2_SUPPORT))
2074	    return FALSE;
2075	if (!radeon_add_encoder(pScrn,
2076				radeon_get_encoder_id_from_supported_device(pScrn,
2077									    ATOM_DEVICE_DFP1_SUPPORT,
2078									    0),
2079				ATOM_DEVICE_DFP1_SUPPORT))
2080	    return FALSE;
2081
2082	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
2083	info->BiosConnector[1].load_detection = FALSE;
2084	info->BiosConnector[1].ddc_i2c.valid = FALSE;
2085	info->BiosConnector[1].valid = TRUE;
2086	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
2087	if (!radeon_add_encoder(pScrn,
2088				radeon_get_encoder_id_from_supported_device(pScrn,
2089									    ATOM_DEVICE_TV1_SUPPORT,
2090									    2),
2091				ATOM_DEVICE_TV1_SUPPORT))
2092	    return FALSE;
2093	return TRUE;
2094    case RADEON_MAC_IMAC_G5_ISIGHT:
2095	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
2096	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
2097	info->BiosConnector[0].valid = TRUE;
2098	info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT;
2099	if (!radeon_add_encoder(pScrn,
2100				radeon_get_encoder_id_from_supported_device(pScrn,
2101									    ATOM_DEVICE_DFP1_SUPPORT,
2102									    0),
2103				ATOM_DEVICE_DFP1_SUPPORT))
2104	    return FALSE;
2105
2106	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
2107	info->BiosConnector[1].load_detection = FALSE;
2108	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2109	info->BiosConnector[1].valid = TRUE;
2110	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
2111	if (!radeon_add_encoder(pScrn,
2112				radeon_get_encoder_id_from_supported_device(pScrn,
2113									    ATOM_DEVICE_CRT2_SUPPORT,
2114									    2),
2115				ATOM_DEVICE_CRT2_SUPPORT))
2116	    return FALSE;
2117
2118	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
2119	info->BiosConnector[2].load_detection = FALSE;
2120	info->BiosConnector[2].ddc_i2c.valid = FALSE;
2121	info->BiosConnector[2].valid = TRUE;
2122	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
2123	if (!radeon_add_encoder(pScrn,
2124				radeon_get_encoder_id_from_supported_device(pScrn,
2125									    ATOM_DEVICE_TV1_SUPPORT,
2126									    2),
2127				ATOM_DEVICE_TV1_SUPPORT))
2128	    return FALSE;
2129	return TRUE;
2130    case RADEON_MAC_EMAC:
2131	/* eMac G4 800/1.0 with radeon 7500, no EDID on internal monitor
2132	 * later eMac's (G4 1.25/1.42) with radeon 9200 and 9600 may have
2133	 * different ddc setups.  need to verify
2134	 */
2135	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2136	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
2137	info->BiosConnector[0].valid = TRUE;
2138	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
2139	if (!radeon_add_encoder(pScrn,
2140				radeon_get_encoder_id_from_supported_device(pScrn,
2141									    ATOM_DEVICE_CRT1_SUPPORT,
2142									    1),
2143				ATOM_DEVICE_CRT1_SUPPORT))
2144	    return FALSE;
2145
2146	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
2147	info->BiosConnector[1].load_detection = FALSE;
2148	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2149	info->BiosConnector[1].valid = TRUE;
2150	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
2151	if (!radeon_add_encoder(pScrn,
2152				radeon_get_encoder_id_from_supported_device(pScrn,
2153									    ATOM_DEVICE_CRT2_SUPPORT,
2154									    2),
2155				ATOM_DEVICE_CRT2_SUPPORT))
2156	    return FALSE;
2157
2158	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
2159	info->BiosConnector[2].load_detection = FALSE;
2160	info->BiosConnector[2].ddc_i2c.valid = FALSE;
2161	info->BiosConnector[2].valid = TRUE;
2162	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
2163	if (!radeon_add_encoder(pScrn,
2164				radeon_get_encoder_id_from_supported_device(pScrn,
2165									    ATOM_DEVICE_TV1_SUPPORT,
2166									    2),
2167				ATOM_DEVICE_TV1_SUPPORT))
2168	    return FALSE;
2169	return TRUE;
2170    default:
2171	return FALSE;
2172    }
2173
2174    return FALSE;
2175}
2176#endif
2177
2178static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
2179{
2180    RADEONInfoPtr info       = RADEONPTR(pScrn);
2181    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
2182
2183    if (IS_AVIVO_VARIANT)
2184	return;
2185
2186    if (!pRADEONEnt->HasCRTC2) {
2187	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2188	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
2189	info->BiosConnector[0].valid = TRUE;
2190	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
2191	radeon_add_encoder(pScrn,
2192			   radeon_get_encoder_id_from_supported_device(pScrn,
2193								       ATOM_DEVICE_CRT1_SUPPORT,
2194								       1),
2195			   ATOM_DEVICE_CRT1_SUPPORT);
2196	return;
2197    }
2198
2199    if (info->IsMobility) {
2200	/* Below is the most common setting, but may not be true */
2201	if (info->IsIGP) {
2202	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
2203	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
2204	    info->BiosConnector[0].valid = TRUE;
2205	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
2206	    radeon_add_encoder(pScrn,
2207			       radeon_get_encoder_id_from_supported_device(pScrn,
2208									   ATOM_DEVICE_LCD1_SUPPORT,
2209									   0),
2210			       ATOM_DEVICE_LCD1_SUPPORT);
2211
2212	    /* IGP only has TVDAC */
2213	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
2214		(info->ChipFamily == CHIP_FAMILY_RS480))
2215		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
2216	    else
2217		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2218	    info->BiosConnector[1].load_detection = FALSE;
2219	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2220	    info->BiosConnector[1].valid = TRUE;
2221	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
2222	    radeon_add_encoder(pScrn,
2223			       radeon_get_encoder_id_from_supported_device(pScrn,
2224									   ATOM_DEVICE_CRT1_SUPPORT,
2225									   2),
2226			       ATOM_DEVICE_CRT1_SUPPORT);
2227	} else {
2228#if defined(__powerpc__)
2229	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
2230#else
2231	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
2232#endif
2233	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
2234	    info->BiosConnector[0].valid = TRUE;
2235	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
2236	    radeon_add_encoder(pScrn,
2237			       radeon_get_encoder_id_from_supported_device(pScrn,
2238									   ATOM_DEVICE_LCD1_SUPPORT,
2239									   0),
2240			       ATOM_DEVICE_LCD1_SUPPORT);
2241
2242	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2243	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2244	    info->BiosConnector[1].valid = TRUE;
2245	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
2246	    radeon_add_encoder(pScrn,
2247			       radeon_get_encoder_id_from_supported_device(pScrn,
2248									   ATOM_DEVICE_CRT1_SUPPORT,
2249									   1),
2250			       ATOM_DEVICE_CRT1_SUPPORT);
2251	}
2252    } else {
2253	/* Below is the most common setting, but may not be true */
2254	if (info->IsIGP) {
2255	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
2256		(info->ChipFamily == CHIP_FAMILY_RS480))
2257		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
2258	    else
2259		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2260	    info->BiosConnector[0].load_detection = FALSE;
2261	    info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
2262	    info->BiosConnector[0].valid = TRUE;
2263	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
2264	    radeon_add_encoder(pScrn,
2265			       radeon_get_encoder_id_from_supported_device(pScrn,
2266									   ATOM_DEVICE_CRT1_SUPPORT,
2267									   1),
2268			       ATOM_DEVICE_CRT1_SUPPORT);
2269
2270	    /* not sure what a good default DDCType for DVI on
2271	     * IGP desktop chips is
2272	     */
2273	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
2274	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
2275	    info->BiosConnector[1].valid = TRUE;
2276	    info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT;
2277	    radeon_add_encoder(pScrn,
2278			       radeon_get_encoder_id_from_supported_device(pScrn,
2279									   ATOM_DEVICE_DFP1_SUPPORT,
2280									   0),
2281			       ATOM_DEVICE_DFP1_SUPPORT);
2282	} else {
2283	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
2284	    info->BiosConnector[0].load_detection = FALSE;
2285	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
2286	    info->BiosConnector[0].valid = TRUE;
2287	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
2288	    radeon_add_encoder(pScrn,
2289			       radeon_get_encoder_id_from_supported_device(pScrn,
2290									   ATOM_DEVICE_CRT2_SUPPORT,
2291									   2),
2292			       ATOM_DEVICE_CRT2_SUPPORT);
2293	    radeon_add_encoder(pScrn,
2294			       radeon_get_encoder_id_from_supported_device(pScrn,
2295									   ATOM_DEVICE_DFP1_SUPPORT,
2296									   0),
2297			       ATOM_DEVICE_DFP1_SUPPORT);
2298
2299#if defined(__powerpc__)
2300	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2301	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
2302	    info->BiosConnector[1].valid = TRUE;
2303	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
2304	    radeon_add_encoder(pScrn,
2305			       radeon_get_encoder_id_from_supported_device(pScrn,
2306									   ATOM_DEVICE_CRT1_SUPPORT,
2307									   1),
2308			       ATOM_DEVICE_CRT1_SUPPORT);
2309	    radeon_add_encoder(pScrn,
2310			       radeon_get_encoder_id_from_supported_device(pScrn,
2311									   ATOM_DEVICE_DFP2_SUPPORT,
2312									   0),
2313			       ATOM_DEVICE_DFP2_SUPPORT);
2314#else
2315	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2316	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
2317	    info->BiosConnector[1].valid = TRUE;
2318	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
2319	    radeon_add_encoder(pScrn,
2320			       radeon_get_encoder_id_from_supported_device(pScrn,
2321									   ATOM_DEVICE_CRT1_SUPPORT,
2322									   1),
2323			       ATOM_DEVICE_CRT1_SUPPORT);
2324#endif
2325	}
2326    }
2327
2328    if (info->InternalTVOut) {
2329	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
2330	info->BiosConnector[2].load_detection = FALSE;
2331	info->BiosConnector[2].ddc_i2c.valid = FALSE;
2332	info->BiosConnector[2].valid = TRUE;
2333	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
2334	radeon_add_encoder(pScrn,
2335			       radeon_get_encoder_id_from_supported_device(pScrn,
2336									   ATOM_DEVICE_TV1_SUPPORT,
2337									   2),
2338			       ATOM_DEVICE_TV1_SUPPORT);
2339    }
2340
2341    /* Some cards have the DDC lines swapped and we have no way to
2342     * detect it yet (Mac cards)
2343     */
2344    if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
2345	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
2346	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
2347    }
2348}
2349
2350#if defined(__powerpc__)
2351
2352/*
2353 * Returns RADEONMacModel or 0 based on lines 'detected as' and 'machine'
2354 * in /proc/cpuinfo (on Linux) */
2355static RADEONMacModel RADEONDetectMacModel(ScrnInfoPtr pScrn)
2356{
2357    RADEONInfoPtr info = RADEONPTR(pScrn);
2358    RADEONMacModel ret = 0;
2359#ifdef __linux__
2360    char cpuline[50];  /* 50 should be sufficient for our purposes */
2361    FILE *f = fopen ("/proc/cpuinfo", "r");
2362
2363    /* Some macs (minis and powerbooks) use internal tmds, others use external tmds
2364     * and not just for dual-link TMDS, it shows up with single-link as well.
2365     * Unforunately, there doesn't seem to be any good way to figure it out.
2366     */
2367
2368    /*
2369     * PowerBook5,[1-5]: external tmds, single-link
2370     * PowerBook5,[789]: external tmds, dual-link
2371     * PowerBook5,6:     external tmds, single-link or dual-link
2372     * need to add another option to specify the external tmds chip
2373     * or find out what's used and add it.
2374     */
2375
2376
2377    if (f != NULL) {
2378	while (fgets(cpuline, sizeof cpuline, f)) {
2379	    if (!strncmp(cpuline, "machine", strlen ("machine"))) {
2380		if (strstr(cpuline, "PowerBook5,1") ||
2381		    strstr(cpuline, "PowerBook5,2") ||
2382		    strstr(cpuline, "PowerBook5,3") ||
2383		    strstr(cpuline, "PowerBook5,4") ||
2384		    strstr(cpuline, "PowerBook5,5")) {
2385		    ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* single link */
2386		    info->ext_tmds_chip = RADEON_SIL_164; /* works on 5,2 */
2387		    break;
2388		}
2389
2390		if (strstr(cpuline, "PowerBook5,6")) {
2391		    ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual or single link */
2392		    break;
2393		}
2394
2395		if (strstr(cpuline, "PowerBook5,7") ||
2396		    strstr(cpuline, "PowerBook5,8") ||
2397		    strstr(cpuline, "PowerBook5,9")) {
2398		    ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual link */
2399		    info->ext_tmds_chip = RADEON_SIL_1178; /* guess */
2400		    break;
2401		}
2402
2403		if (strstr(cpuline, "PowerBook3,3")) {
2404		    ret = RADEON_MAC_POWERBOOK_VGA; /* vga rather than dvi */
2405		    break;
2406		}
2407
2408		if (strstr(cpuline, "PowerMac10,1")) {
2409		    ret = RADEON_MAC_MINI_INTERNAL; /* internal tmds */
2410		    break;
2411		}
2412		if (strstr(cpuline, "PowerMac10,2")) {
2413		    ret = RADEON_MAC_MINI_EXTERNAL; /* external tmds */
2414		    break;
2415		}
2416	    } else if (!strncmp(cpuline, "detected as", strlen("detected as"))) {
2417		if (strstr(cpuline, "iBook")) {
2418		    ret = RADEON_MAC_IBOOK;
2419		    break;
2420		} else if (strstr(cpuline, "PowerBook")) {
2421		    ret = RADEON_MAC_POWERBOOK_INTERNAL; /* internal tmds */
2422		    break;
2423		} else if (strstr(cpuline, "iMac G5 (iSight)")) {
2424		    ret = RADEON_MAC_IMAC_G5_ISIGHT;
2425		    break;
2426		} else if (strstr(cpuline, "eMac")) {
2427		    ret = RADEON_MAC_EMAC;
2428		    break;
2429		}
2430
2431		/* No known PowerMac model detected */
2432		break;
2433	    }
2434	}
2435
2436	fclose (f);
2437    } else
2438	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2439		   "Cannot detect PowerMac model because /proc/cpuinfo not "
2440		   "readable.\n");
2441
2442#endif /* __linux */
2443
2444    if (ret) {
2445	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Detected %s.\n",
2446		   ret == RADEON_MAC_POWERBOOK_EXTERNAL ? "PowerBook with external DVI" :
2447		   ret == RADEON_MAC_POWERBOOK_INTERNAL ? "PowerBook with integrated DVI" :
2448		   ret == RADEON_MAC_POWERBOOK_VGA ? "PowerBook with VGA" :
2449		   ret == RADEON_MAC_IBOOK ? "iBook" :
2450		   ret == RADEON_MAC_MINI_EXTERNAL ? "Mac Mini with external DVI" :
2451		   ret == RADEON_MAC_MINI_INTERNAL ? "Mac Mini with integrated DVI" :
2452		   "iMac G5 iSight");
2453	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2454		   "If this is not correct, try Option \"MacModel\" and "
2455		   "consider reporting to the\n");
2456	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2457		   "xorg-driver-ati@lists.x.org mailing list"
2458#ifdef __linux__
2459		   " with the contents of /proc/cpuinfo"
2460#endif
2461		   ".\n");
2462    }
2463
2464    return ret;
2465}
2466
2467#endif /* __powerpc__ */
2468
2469static int
2470radeon_output_clones (ScrnInfoPtr pScrn, xf86OutputPtr output)
2471{
2472    RADEONInfoPtr info = RADEONPTR(pScrn);
2473    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2474    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
2475    int			o;
2476    int			index_mask = 0;
2477
2478    /* DIG routing gets problematic */
2479    if (IS_DCE32_VARIANT)
2480	return index_mask;
2481
2482    /* LVDS is too wacky */
2483    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))
2484	return index_mask;
2485
2486    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
2487	return index_mask;
2488
2489    for (o = 0; o < config->num_output; o++) {
2490	xf86OutputPtr clone = config->output[o];
2491	RADEONOutputPrivatePtr radeon_clone = clone->driver_private;
2492
2493	if (output == clone) /* don't clone yourself */
2494	    continue;
2495	else if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) /* LVDS */
2496	    continue;
2497	else if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) /* TV */
2498	    continue;
2499	else
2500	    index_mask |= (1 << o);
2501    }
2502
2503    return index_mask;
2504}
2505
2506static xf86OutputPtr
2507RADEONOutputCreate(ScrnInfoPtr pScrn, const char *name, int i)
2508{
2509    char buf[32];
2510    sprintf(buf, name, i);
2511    return xf86OutputCreate(pScrn, &radeon_output_funcs, buf);
2512}
2513
2514/*
2515 * initialise the static data sos we don't have to re-do at randr change */
2516Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
2517{
2518    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2519    RADEONInfoPtr info       = RADEONPTR(pScrn);
2520    xf86OutputPtr output;
2521    char *optstr;
2522    int i;
2523    int num_vga = 0;
2524    int num_dvi = 0;
2525    int num_hdmi = 0;
2526    int num_dp = 0;
2527
2528    /* We first get the information about all connectors from BIOS.
2529     * This is how the card is phyiscally wired up.
2530     * The information should be correct even on a OEM card.
2531     */
2532    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
2533	info->encoders[i] = NULL;
2534	info->BiosConnector[i].valid = FALSE;
2535	info->BiosConnector[i].load_detection = TRUE;
2536	info->BiosConnector[i].shared_ddc = FALSE;
2537	info->BiosConnector[i].ddc_i2c.valid = FALSE;
2538	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
2539	info->BiosConnector[i].devices = 0;
2540    }
2541
2542#if defined(__powerpc__)
2543    info->MacModel = 0;
2544    optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL);
2545    if (optstr) {
2546	if (!strncmp("ibook", optstr, strlen("ibook")))
2547	    info->MacModel = RADEON_MAC_IBOOK;
2548	else if (!strncmp("powerbook-duallink", optstr, strlen("powerbook-duallink"))) /* alias */
2549	    info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL;
2550	else if (!strncmp("powerbook-external", optstr, strlen("powerbook-external")))
2551	    info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL;
2552	else if (!strncmp("powerbook-internal", optstr, strlen("powerbook-internal")))
2553	    info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL;
2554	else if (!strncmp("powerbook-vga", optstr, strlen("powerbook-vga")))
2555	    info->MacModel = RADEON_MAC_POWERBOOK_VGA;
2556	else if (!strncmp("powerbook", optstr, strlen("powerbook"))) /* alias */
2557	    info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL;
2558	else if (!strncmp("mini-internal", optstr, strlen("mini-internal")))
2559	    info->MacModel = RADEON_MAC_MINI_INTERNAL;
2560	else if (!strncmp("mini-external", optstr, strlen("mini-external")))
2561	    info->MacModel = RADEON_MAC_MINI_EXTERNAL;
2562	else if (!strncmp("mini", optstr, strlen("mini"))) /* alias */
2563	    info->MacModel = RADEON_MAC_MINI_EXTERNAL;
2564	else if (!strncmp("imac-g5-isight", optstr, strlen("imac-g5-isight")))
2565	    info->MacModel = RADEON_MAC_IMAC_G5_ISIGHT;
2566	else if (!strncmp("emac", optstr, strlen("emac")))
2567	    info->MacModel = RADEON_MAC_EMAC;
2568	else {
2569	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid Mac Model: %s\n", optstr);
2570	}
2571    }
2572
2573    if (!info->MacModel) {
2574	info->MacModel = RADEONDetectMacModel(pScrn);
2575    }
2576
2577    if (info->MacModel){
2578	if (!RADEONSetupAppleConnectors(pScrn))
2579	    RADEONSetupGenericConnectors(pScrn);
2580    } else
2581#endif
2582    if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) {
2583	RADEONSetupGenericConnectors(pScrn);
2584    } else {
2585	if (!RADEONGetConnectorInfoFromBIOS(pScrn))
2586	    RADEONSetupGenericConnectors(pScrn);
2587    }
2588
2589    /* parse connector table option */
2590    optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
2591
2592    if (optstr) {
2593	unsigned int ddc_line[2];
2594	int DACType[2], TMDSType[2];
2595
2596	for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
2597	    info->BiosConnector[i].valid = FALSE;
2598	}
2599
2600	if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u",
2601		   &ddc_line[0],
2602		   &DACType[0],
2603		   &TMDSType[0],
2604		   &info->BiosConnector[0].ConnectorType,
2605		   &ddc_line[1],
2606		   &DACType[1],
2607		   &TMDSType[1],
2608		   &info->BiosConnector[1].ConnectorType) != 8) {
2609	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr);
2610	    return FALSE;
2611	}
2612
2613	for (i = 0; i < 2; i++) {
2614	    info->BiosConnector[i].valid = TRUE;
2615	    info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(ddc_line[i]);
2616	    switch (DACType[i]) {
2617	    case 1:
2618		info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
2619		if (!radeon_add_encoder(pScrn,
2620					radeon_get_encoder_id_from_supported_device(pScrn,
2621										    ATOM_DEVICE_CRT1_SUPPORT,
2622										    1),
2623					ATOM_DEVICE_CRT1_SUPPORT))
2624		    return FALSE;
2625		info->BiosConnector[i].load_detection = TRUE;
2626		break;
2627	    case 2:
2628		info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
2629		if (!radeon_add_encoder(pScrn,
2630					radeon_get_encoder_id_from_supported_device(pScrn,
2631										    ATOM_DEVICE_CRT1_SUPPORT,
2632										    2),
2633					ATOM_DEVICE_CRT1_SUPPORT))
2634		    return FALSE;
2635		info->BiosConnector[i].load_detection = FALSE;
2636		break;
2637	    }
2638	    switch (TMDSType[i]) {
2639	    case 1:
2640		info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
2641		if (!radeon_add_encoder(pScrn,
2642					radeon_get_encoder_id_from_supported_device(pScrn,
2643										    ATOM_DEVICE_DFP1_SUPPORT,
2644										    0),
2645					ATOM_DEVICE_DFP1_SUPPORT))
2646		    return FALSE;
2647		break;
2648	    case 2:
2649		info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
2650		if (!radeon_add_encoder(pScrn,
2651					radeon_get_encoder_id_from_supported_device(pScrn,
2652										    ATOM_DEVICE_DFP2_SUPPORT,
2653										    0),
2654					ATOM_DEVICE_DFP2_SUPPORT))
2655		    return FALSE;
2656		break;
2657	    }
2658	}
2659    }
2660
2661    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
2662	if (info->BiosConnector[i].valid) {
2663	    RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType;
2664	    if ((conntype == CONNECTOR_DVI_D) ||
2665		(conntype == CONNECTOR_DVI_I) ||
2666		(conntype == CONNECTOR_DVI_A)) {
2667		num_dvi++;
2668	    } else if (conntype == CONNECTOR_VGA) {
2669		num_vga++;
2670	    } else if ((conntype == CONNECTOR_HDMI_TYPE_A) ||
2671		       (conntype == CONNECTOR_HDMI_TYPE_B)) {
2672		num_hdmi++;
2673	    } else if (conntype == CONNECTOR_DISPLAY_PORT) {
2674		num_dp++;
2675	    }
2676	}
2677    }
2678
2679    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
2680	if (info->BiosConnector[i].valid) {
2681	    RADEONOutputPrivatePtr radeon_output;
2682	    RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType;
2683
2684	    if (conntype == CONNECTOR_NONE)
2685		continue;
2686
2687	    radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
2688	    if (!radeon_output) {
2689		return FALSE;
2690	    }
2691	    radeon_output->MonType = MT_UNKNOWN;
2692	    radeon_output->ConnectorType = conntype;
2693	    radeon_output->devices = info->BiosConnector[i].devices;
2694	    radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c;
2695	    radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info;
2696	    radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc;
2697	    radeon_output->load_detection = info->BiosConnector[i].load_detection;
2698	    radeon_output->linkb = info->BiosConnector[i].linkb;
2699	    radeon_output->connector_id = info->BiosConnector[i].connector_object;
2700
2701	    if ((conntype == CONNECTOR_DVI_D) ||
2702		(conntype == CONNECTOR_DVI_I) ||
2703		(conntype == CONNECTOR_DVI_A)) {
2704		output = RADEONOutputCreate(pScrn, "DVI-%d", --num_dvi);
2705	    } else if (conntype == CONNECTOR_VGA) {
2706		output = RADEONOutputCreate(pScrn, "VGA-%d", --num_vga);
2707	    } else if ((conntype == CONNECTOR_HDMI_TYPE_A) ||
2708		       (conntype == CONNECTOR_HDMI_TYPE_B)) {
2709		output = RADEONOutputCreate(pScrn, "HDMI-%d", --num_hdmi);
2710	    } else if (conntype == CONNECTOR_DISPLAY_PORT) {
2711		output = RADEONOutputCreate(pScrn, "DisplayPort-%d", --num_dp);
2712	    } else {
2713		output = RADEONOutputCreate(pScrn,
2714					    ConnectorTypeName[conntype], 0);
2715	    }
2716
2717	    if (!output) {
2718		return FALSE;
2719	    }
2720	    output->driver_private = radeon_output;
2721	    output->possible_crtcs = 1;
2722	    /* crtc2 can drive LVDS, it just doesn't have RMX */
2723	    if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)))
2724		output->possible_crtcs |= 2;
2725
2726	    /* we can clone the DACs, and probably TV-out,
2727	       but I'm not sure it's worth the trouble */
2728	    output->possible_clones = 0;
2729
2730	    RADEONInitConnector(output);
2731	}
2732    }
2733
2734    for (i = 0; i < xf86_config->num_output; i++) {
2735	xf86OutputPtr output = xf86_config->output[i];
2736
2737	output->possible_clones = radeon_output_clones(pScrn, output);
2738    }
2739
2740    return TRUE;
2741}
2742
2743