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