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