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