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