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