legacy_output.c revision 209ff23f
1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <string.h>
34#include <stdio.h>
35
36/* X and server generic header files */
37#include "xf86.h"
38#include "xf86_OSproc.h"
39#include "vgaHW.h"
40#include "xf86Modes.h"
41
42/* Driver data structures */
43#include "radeon.h"
44#include "radeon_reg.h"
45#include "radeon_macros.h"
46#include "radeon_probe.h"
47#include "radeon_version.h"
48#include "radeon_tv.h"
49#include "radeon_atombios.h"
50
51static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
52static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
53static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
54static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
55
56void
57RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
58			  RADEONSavePtr restore)
59{
60    RADEONInfoPtr  info       = RADEONPTR(pScrn);
61    unsigned char *RADEONMMIO = info->MMIO;
62
63    if (IS_R300_VARIANT)
64	OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
65
66    OUTREGP(RADEON_DAC_CNTL,
67	    restore->dac_cntl,
68	    RADEON_DAC_RANGE_CNTL |
69	    RADEON_DAC_BLANKING);
70
71    OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
72
73    if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
74	(info->ChipFamily != CHIP_FAMILY_R200))
75    OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
76
77    OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
78
79    if ((info->ChipFamily == CHIP_FAMILY_R200) ||
80	IS_R300_VARIANT) {
81	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
82    } else {
83	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
84    }
85
86    OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
87
88    /* R200 DAC connected via DVO */
89    if (info->ChipFamily == CHIP_FAMILY_R200)
90	OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
91}
92
93
94/* Write TMDS registers */
95void
96RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
97{
98    RADEONInfoPtr  info       = RADEONPTR(pScrn);
99    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
100    unsigned char *RADEONMMIO = info->MMIO;
101
102    OUTREG(RADEON_TMDS_PLL_CNTL,        restore->tmds_pll_cntl);
103    OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
104    OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
105
106    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
107	(info->ChipFamily == CHIP_FAMILY_RS480)) {
108	OUTREG(RS400_FP_2ND_GEN_CNTL, restore->fp_2nd_gen_cntl);
109	/*OUTREG(RS400_TMDS2_CNTL, restore->tmds2_cntl);*/
110	OUTREG(RS400_TMDS2_TRANSMITTER_CNTL, restore->tmds2_transmitter_cntl);
111    }
112
113    /* old AIW Radeon has some BIOS initialization problem
114     * with display buffer underflow, only occurs to DFP
115     */
116    if (!pRADEONEnt->HasCRTC2)
117	OUTREG(RADEON_GRPH_BUFFER_CNTL,
118	       INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
119
120}
121
122/* Write FP2 registers */
123void
124RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
125{
126    RADEONInfoPtr  info       = RADEONPTR(pScrn);
127    unsigned char *RADEONMMIO = info->MMIO;
128
129    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
130
131    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
132	(info->ChipFamily == CHIP_FAMILY_RS480))
133	OUTREG(RS400_FP2_2_GEN_CNTL, restore->fp2_2_gen_cntl);
134}
135
136/* Write RMX registers */
137void
138RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
139{
140    RADEONInfoPtr  info       = RADEONPTR(pScrn);
141    unsigned char *RADEONMMIO = info->MMIO;
142
143    OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
144    OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
145    OUTREG(RADEON_CRTC_MORE_CNTL,       restore->crtc_more_cntl);
146    OUTREG(RADEON_FP_HORZ_VERT_ACTIVE,  restore->fp_horz_vert_active);
147    OUTREG(RADEON_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
148    OUTREG(RADEON_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
149    OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
150    OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
151
152}
153
154/* Write LVDS registers */
155void
156RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
157{
158    RADEONInfoPtr  info       = RADEONPTR(pScrn);
159    unsigned char *RADEONMMIO = info->MMIO;
160
161    if (info->IsMobility) {
162	OUTREG(RADEON_LVDS_GEN_CNTL,  restore->lvds_gen_cntl);
163	/*OUTREG(RADEON_LVDS_PLL_CNTL,  restore->lvds_pll_cntl);*/
164
165	if (info->ChipFamily == CHIP_FAMILY_RV410) {
166	    OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
167	}
168    }
169
170}
171
172void
173RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
174{
175    RADEONInfoPtr  info       = RADEONPTR(pScrn);
176    unsigned char *RADEONMMIO = info->MMIO;
177
178    save->dac_cntl              = INREG(RADEON_DAC_CNTL);
179    save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
180    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
181    save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
182    save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
183    save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
184    save->dac_macro_cntl        = INREG(RADEON_DAC_MACRO_CNTL);
185    save->gpiopad_a             = INREG(RADEON_GPIOPAD_A);
186
187}
188
189/* Read flat panel registers */
190void
191RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
192{
193    RADEONInfoPtr  info       = RADEONPTR(pScrn);
194    unsigned char *RADEONMMIO = info->MMIO;
195
196    save->fp_gen_cntl          = INREG(RADEON_FP_GEN_CNTL);
197    save->fp2_gen_cntl          = INREG (RADEON_FP2_GEN_CNTL);
198    save->fp_horz_stretch      = INREG(RADEON_FP_HORZ_STRETCH);
199    save->fp_vert_stretch      = INREG(RADEON_FP_VERT_STRETCH);
200    save->fp_horz_vert_active  = INREG(RADEON_FP_HORZ_VERT_ACTIVE);
201    save->crtc_more_cntl       = INREG(RADEON_CRTC_MORE_CNTL);
202    save->lvds_gen_cntl        = INREG(RADEON_LVDS_GEN_CNTL);
203    save->lvds_pll_cntl        = INREG(RADEON_LVDS_PLL_CNTL);
204    save->tmds_pll_cntl        = INREG(RADEON_TMDS_PLL_CNTL);
205    save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL);
206
207    save->fp_h_sync_strt_wid   = INREG(RADEON_FP_H_SYNC_STRT_WID);
208    save->fp_v_sync_strt_wid   = INREG(RADEON_FP_V_SYNC_STRT_WID);
209    save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP);
210    save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP);
211
212    if (info->ChipFamily == CHIP_FAMILY_RV280) {
213	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
214	save->tmds_pll_cntl ^= (1 << 22);
215    }
216
217    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
218	(info->ChipFamily == CHIP_FAMILY_RS480)) {
219	save->fp_2nd_gen_cntl         = INREG(RS400_FP_2ND_GEN_CNTL);
220	save->fp2_2_gen_cntl          = INREG(RS400_FP2_2_GEN_CNTL);
221	save->tmds2_cntl              = INREG(RS400_TMDS2_CNTL);
222	save->tmds2_transmitter_cntl  = INREG(RS400_TMDS2_TRANSMITTER_CNTL);
223    }
224
225}
226
227Bool
228RADEONDVOReadByte(I2CDevPtr dvo, int addr, uint8_t *ch)
229{
230    if (!xf86I2CReadByte(dvo, addr, ch)) {
231	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
232		   "Unable to read from %s Slave %d.\n",
233		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
234	return FALSE;
235    }
236    return TRUE;
237}
238
239Bool
240RADEONDVOWriteByte(I2CDevPtr dvo, int addr, uint8_t ch)
241{
242    if (!xf86I2CWriteByte(dvo, addr, ch)) {
243	xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
244		   "Unable to write to %s Slave %d.\n",
245		   dvo->pI2CBus->BusName, dvo->SlaveAddr);
246	return FALSE;
247    }
248    return TRUE;
249}
250
251I2CDevPtr
252RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
253{
254    I2CDevPtr dvo;
255
256    dvo = xcalloc(1, sizeof(I2CDevRec));
257    if (dvo == NULL)
258	return NULL;
259
260    dvo->DevName = "RADEON DVO Controller";
261    dvo->SlaveAddr = addr;
262    dvo->pI2CBus = b;
263    dvo->StartTimeout = b->StartTimeout;
264    dvo->BitTimeout = b->BitTimeout;
265    dvo->AcknTimeout = b->AcknTimeout;
266    dvo->ByteTimeout = b->ByteTimeout;
267
268    if (xf86I2CDevInit(dvo)) {
269	return dvo;
270    }
271
272    xfree(dvo);
273    return NULL;
274}
275
276static void
277RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
278{
279    RADEONInfoPtr info = RADEONPTR(pScrn);
280    unsigned char *RADEONMMIO = info->MMIO;
281    RADEONOutputPrivatePtr radeon_output = output->driver_private;
282
283    if (!radeon_output->DVOChip)
284	return;
285
286    OUTREG(radeon_output->dvo_i2c.mask_clk_reg,
287	   INREG(radeon_output->dvo_i2c.mask_clk_reg) &
288	   (uint32_t)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
289
290    if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
291	if (radeon_output->DVOChip) {
292	    switch(info->ext_tmds_chip) {
293	    case RADEON_SIL_164:
294		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
295		RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
296		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
297		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
298		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
299		break;
300#if 0
301		/* needs work see bug 10418 */
302	    case RADEON_SIL_1178:
303		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
304		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
305		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
306		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
307                RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
308                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
309                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
310                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
311                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
312		break;
313#endif
314	    default:
315		break;
316	    }
317	}
318    }
319}
320
321#if 0
322static RADEONMonitorType
323RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
324{
325    RADEONInfoPtr info       = RADEONPTR(pScrn);
326    unsigned char *RADEONMMIO = info->MMIO;
327    int		  bConnected = 0;
328
329    /* the monitor either wasn't connected or it is a non-DDC CRT.
330     * try to probe it
331     */
332    if(IsCrtDac) {
333	unsigned long ulOrigVCLK_ECP_CNTL;
334	unsigned long ulOrigDAC_CNTL;
335	unsigned long ulOrigDAC_MACRO_CNTL;
336	unsigned long ulOrigDAC_EXT_CNTL;
337	unsigned long ulOrigCRTC_EXT_CNTL;
338	unsigned long ulData;
339	unsigned long ulMask;
340
341	ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
342
343	ulData              = ulOrigVCLK_ECP_CNTL;
344	ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb
345				| RADEON_PIXCLK_DAC_ALWAYS_ONb);
346	ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb
347				|RADEON_PIXCLK_DAC_ALWAYS_ONb);
348	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
349
350	ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
351	ulData              = ulOrigCRTC_EXT_CNTL;
352	ulData             |= RADEON_CRTC_CRT_ON;
353	OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
354
355	ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
356	ulData             = ulOrigDAC_EXT_CNTL;
357	ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
358	ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN
359			       |RADEON_DAC_FORCE_DATA_EN
360			       |RADEON_DAC_FORCE_DATA_SEL_MASK);
361	if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
362	    (info->ChipFamily == CHIP_FAMILY_RV280))
363	    ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
364	else
365	    ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
366
367	OUTREG(RADEON_DAC_EXT_CNTL, ulData);
368
369	/* turn on power so testing can go through */
370	ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
371	ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
372	OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
373
374	ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
375	ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
376				  RADEON_DAC_PDWN_B);
377	OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
378
379	/* Enable comparators and set DAC range to PS2 (VGA) output level */
380	ulData = ulOrigDAC_CNTL;
381	ulData |= RADEON_DAC_CMP_EN;
382	ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
383	ulData |= 0x2;
384	OUTREG(RADEON_DAC_CNTL, ulData);
385
386	/* Settle down */
387	usleep(10000);
388
389	/* Read comparators */
390	ulData     = INREG(RADEON_DAC_CNTL);
391	bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
392
393	/* Restore things */
394	ulData    = ulOrigVCLK_ECP_CNTL;
395	ulMask    = 0xFFFFFFFFL;
396	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
397
398	OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );
399	OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
400	OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
401
402	if (!bConnected) {
403	    /* Power DAC down if CRT is not connected */
404            ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
405            ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
406	    	RADEON_DAC_PDWN_B);
407            OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
408
409	    ulData = INREG(RADEON_DAC_CNTL);
410	    ulData |= RADEON_DAC_PDWN;
411	    OUTREG(RADEON_DAC_CNTL, ulData);
412    	}
413    } else { /* TV DAC */
414
415        /* This doesn't seem to work reliably (maybe worse on some OEM cards),
416           for now we always return false. If one wants to connected a
417           non-DDC monitor on the DVI port when CRT port is also connected,
418           he will need to explicitly tell the driver in the config file
419           with Option MonitorLayout.
420        */
421        bConnected = FALSE;
422
423#if 0
424	if (info->ChipFamily == CHIP_FAMILY_R200) {
425	    unsigned long ulOrigGPIO_MONID;
426	    unsigned long ulOrigFP2_GEN_CNTL;
427	    unsigned long ulOrigDISP_OUTPUT_CNTL;
428	    unsigned long ulOrigCRTC2_GEN_CNTL;
429	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
430	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
431	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
432	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
433	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
434	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
435	    unsigned long ulOrigCRTC2_H_TOTAL_DISP;
436	    unsigned long ulOrigCRTC2_V_TOTAL_DISP;
437	    unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
438	    unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
439	    unsigned long ulData, i;
440
441	    ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
442	    ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
443	    ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
444	    ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
445	    ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
446	    ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
447	    ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
448	    ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
449	    ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
450	    ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
451
452	    ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
453	    ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
454	    ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
455	    ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
456
457	    ulData     = INREG(RADEON_GPIO_MONID);
458	    ulData    &= ~RADEON_GPIO_A_0;
459	    OUTREG(RADEON_GPIO_MONID, ulData);
460
461	    OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
462
463	    OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
464
465	    OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
466	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
467	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
468	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
469	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
470	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
471	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
472	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
473	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
474	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
475	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
476
477	    for (i = 0; i < 200; i++) {
478		ulData     = INREG(RADEON_GPIO_MONID);
479		bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
480		if (!bConnected) break;
481
482		usleep(1000);
483	    }
484
485	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
486	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
487	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
488	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
489	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
490	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
491	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
492	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
493	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
494	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
495	    OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
496	    OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
497	    OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
498	    OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
499        } else {
500	    unsigned long ulOrigPIXCLKSDATA;
501	    unsigned long ulOrigTV_MASTER_CNTL;
502	    unsigned long ulOrigTV_DAC_CNTL;
503	    unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
504	    unsigned long ulOrigDAC_CNTL2;
505	    unsigned long ulData;
506	    unsigned long ulMask;
507
508	    ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
509
510	    ulData            = ulOrigPIXCLKSDATA;
511	    ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb
512				  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
513	    ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb
514			  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
515	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
516
517	    ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
518	    ulData               = ulOrigTV_MASTER_CNTL;
519	    ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;
520	    OUTREG(RADEON_TV_MASTER_CNTL, ulData);
521
522	    ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
523	    ulData          = ulOrigDAC_CNTL2;
524	    ulData          &= ~RADEON_DAC2_DAC2_CLK_SEL;
525	    OUTREG(RADEON_DAC_CNTL2, ulData);
526
527	    ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
528
529	    ulData  = 0x00880213;
530	    OUTREG(RADEON_TV_DAC_CNTL, ulData);
531
532	    ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
533
534	    ulData  =  (RADEON_Y_RED_EN
535			| RADEON_C_GRN_EN
536			| RADEON_CMP_BLU_EN
537			| RADEON_RED_MX_FORCE_DAC_DATA
538			| RADEON_GRN_MX_FORCE_DAC_DATA
539			| RADEON_BLU_MX_FORCE_DAC_DATA);
540            if (IS_R300_VARIANT)
541		ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
542	    else
543		ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
544	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
545
546	    usleep(10000);
547
548	    ulData     = INREG(RADEON_TV_DAC_CNTL);
549	    bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
550
551	    ulData    = ulOrigPIXCLKSDATA;
552	    ulMask    = 0xFFFFFFFFL;
553	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
554
555	    OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
556	    OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
557	    OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
558	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
559	}
560#endif
561	return MT_UNKNOWN;
562    }
563
564    return(bConnected ? MT_CRT : MT_NONE);
565}
566#endif
567
568RADEONMonitorType
569legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
570{
571    RADEONInfoPtr info      = RADEONPTR(pScrn);
572    RADEONOutputPrivatePtr radeon_output = output->driver_private;
573    RADEONMonitorType found = MT_NONE;
574
575    if (OUTPUT_IS_TV) {
576	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
577	    if (radeon_output->type == OUTPUT_STV)
578		found = MT_STV;
579	    else
580		found = MT_CTV;
581	} else {
582	    if (info->InternalTVOut) {
583		if (radeon_output->load_detection)
584		    found = radeon_detect_tv(pScrn);
585		else
586		    found = MT_NONE;
587	    }
588	}
589    } else {
590	if (radeon_output->DACType == DAC_PRIMARY) {
591	    if (radeon_output->load_detection)
592		found = radeon_detect_primary_dac(pScrn, TRUE);
593	} else if (radeon_output->DACType == DAC_TVDAC) {
594	    if (radeon_output->load_detection) {
595		if (info->ChipFamily == CHIP_FAMILY_R200)
596		    found = radeon_detect_ext_dac(pScrn);
597		else
598		    found = radeon_detect_tv_dac(pScrn, TRUE);
599	    } else
600		found = MT_NONE;
601	}
602    }
603
604    return found;
605}
606
607/*
608 * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
609 *
610 */
611static void
612RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
613{
614    RADEONInfoPtr  info       = RADEONPTR(pScrn);
615    unsigned char *RADEONMMIO = info->MMIO;
616
617    if (IsPrimaryDAC) {
618	uint32_t dac_cntl;
619	uint32_t dac_macro_cntl = 0;
620	dac_cntl = INREG(RADEON_DAC_CNTL);
621	dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
622	if (IsOn) {
623	    dac_cntl &= ~RADEON_DAC_PDWN;
624	    dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
625				RADEON_DAC_PDWN_G |
626				RADEON_DAC_PDWN_B);
627	} else {
628	    dac_cntl |= RADEON_DAC_PDWN;
629	    dac_macro_cntl |= (RADEON_DAC_PDWN_R |
630			       RADEON_DAC_PDWN_G |
631			       RADEON_DAC_PDWN_B);
632	}
633	OUTREG(RADEON_DAC_CNTL, dac_cntl);
634	OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
635    } else {
636	uint32_t tv_dac_cntl;
637	uint32_t fp2_gen_cntl;
638
639	switch(info->ChipFamily)
640	{
641	case CHIP_FAMILY_R420:
642	case CHIP_FAMILY_RV410:
643	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
644	    if (IsOn) {
645		tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
646				 R420_TV_DAC_GDACPD |
647				 R420_TV_DAC_BDACPD |
648				 RADEON_TV_DAC_BGSLEEP);
649	    } else {
650		tv_dac_cntl |= (R420_TV_DAC_RDACPD |
651				R420_TV_DAC_GDACPD |
652				R420_TV_DAC_BDACPD |
653				RADEON_TV_DAC_BGSLEEP);
654	    }
655	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
656	    break;
657	case CHIP_FAMILY_R200:
658	    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
659	    if (IsOn) {
660		fp2_gen_cntl |= RADEON_FP2_DVO_EN;
661	    } else {
662		fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
663	    }
664	    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
665	    break;
666
667	default:
668	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
669	    if (IsOn) {
670		tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
671				 RADEON_TV_DAC_GDACPD |
672				 RADEON_TV_DAC_BDACPD |
673				 RADEON_TV_DAC_BGSLEEP);
674	    } else {
675		tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
676				RADEON_TV_DAC_GDACPD |
677				RADEON_TV_DAC_BDACPD |
678				RADEON_TV_DAC_BGSLEEP);
679	    }
680	    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
681	    break;
682	}
683    }
684}
685
686/* This is to be used enable/disable displays dynamically */
687static void
688RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
689{
690    ScrnInfoPtr pScrn = output->scrn;
691    RADEONInfoPtr info = RADEONPTR(pScrn);
692    RADEONSavePtr save = info->ModeReg;
693    unsigned char * RADEONMMIO = info->MMIO;
694    unsigned long tmp;
695    RADEONOutputPrivatePtr radeon_output;
696    int tv_dac_change = 0, o;
697    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
698
699    radeon_output = output->driver_private;
700    for (o = 0; o < xf86_config->num_output; o++) {
701	if (output == xf86_config->output[o]) {
702	    break;
703	}
704    }
705
706    if (bEnable) {
707	/*ErrorF("enable montype: %d\n", radeon_output->MonType);*/
708	if (radeon_output->MonType == MT_CRT) {
709	    if (radeon_output->DACType == DAC_PRIMARY) {
710		info->output_crt1 |= (1 << o);
711		tmp = INREG(RADEON_CRTC_EXT_CNTL);
712		tmp |= RADEON_CRTC_CRT_ON;
713		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
714		save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
715		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
716	    } else if (radeon_output->DACType == DAC_TVDAC) {
717		info->output_crt2 |= (1 << o);
718		if (info->ChipFamily == CHIP_FAMILY_R200) {
719		    tmp = INREG(RADEON_FP2_GEN_CNTL);
720		    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
721		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
722		    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
723		} else {
724		    tmp = INREG(RADEON_CRTC2_GEN_CNTL);
725		    tmp |= RADEON_CRTC2_CRT2_ON;
726		    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
727		    save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
728		}
729		tv_dac_change = 1;
730		/* IGP chips seem to use a mix of Primary and TVDAC controls */
731		if (info->IsIGP) {
732		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
733		    tmp |= RADEON_CRTC_CRT_ON;
734		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
735		    save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
736		    RADEONDacPowerSet(pScrn, bEnable, TRUE);
737		}
738	    }
739	} else if (radeon_output->MonType == MT_DFP) {
740	    if (radeon_output->TMDSType == TMDS_INT) {
741		info->output_dfp1 |= (1 << o);
742		tmp = INREG(RADEON_FP_GEN_CNTL);
743		tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
744		OUTREG(RADEON_FP_GEN_CNTL, tmp);
745		save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
746		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
747		    (info->ChipFamily == CHIP_FAMILY_RS480)) {
748		    tmp = INREG(RS400_FP_2ND_GEN_CNTL);
749		    tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
750		    OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
751		    save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON |
752					      RS400_TMDS_2ND_EN);
753		}
754	    } else if (radeon_output->TMDSType == TMDS_EXT) {
755		info->output_dfp2 |= (1 << o);
756		tmp = INREG(RADEON_FP2_GEN_CNTL);
757		tmp &= ~RADEON_FP2_BLANK_EN;
758		tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
759		OUTREG(RADEON_FP2_GEN_CNTL, tmp);
760		save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
761		save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
762		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
763		    (info->ChipFamily == CHIP_FAMILY_RS480)) {
764		    tmp = INREG(RS400_FP2_2_GEN_CNTL);
765		    tmp &= ~RS400_FP2_2_BLANK_EN;
766		    tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
767		    OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
768		    save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
769		    save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN;
770		}
771	    }
772	} else if (radeon_output->MonType == MT_LCD) {
773	    info->output_lcd1 |= (1 << o);
774	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
775	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
776	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
777	    usleep (radeon_output->PanelPwrDly * 1000);
778	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
779	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
780	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
781	} else if (radeon_output->MonType == MT_STV ||
782		   radeon_output->MonType == MT_CTV) {
783	    info->output_tv1 |= (1 << o);
784	    tmp = INREG(RADEON_TV_MASTER_CNTL);
785	    tmp |= RADEON_TV_ON;
786	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
787	    tv_dac_change = 2;
788	    radeon_output->tv_on = TRUE;
789	}
790    } else {
791	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
792	if (radeon_output->MonType == MT_CRT) {
793	    if (radeon_output->DACType == DAC_PRIMARY) {
794		info->output_crt1 &= ~(1 << o);
795		if (!info->output_crt1) {
796		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
797		    tmp &= ~RADEON_CRTC_CRT_ON;
798		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
799		    save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
800		    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
801		}
802	    } else if (radeon_output->DACType == DAC_TVDAC) {
803		info->output_crt2 &= ~(1 << o);
804		tv_dac_change = 1;
805		if (!info->output_crt2) {
806		    if (info->ChipFamily == CHIP_FAMILY_R200) {
807			tmp = INREG(RADEON_FP2_GEN_CNTL);
808			tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
809			OUTREG(RADEON_FP2_GEN_CNTL, tmp);
810			save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
811		    } else {
812			tmp = INREG(RADEON_CRTC2_GEN_CNTL);
813			tmp &= ~RADEON_CRTC2_CRT2_ON;
814			OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
815			save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
816		    }
817		}
818		/* IGP chips seem to use a mix of Primary and TVDAC controls */
819		if (info->IsIGP) {
820		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
821		    tmp &= ~RADEON_CRTC_CRT_ON;
822		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
823		    save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
824		    RADEONDacPowerSet(pScrn, bEnable, TRUE);
825		}
826	    }
827	} else if (radeon_output->MonType == MT_DFP) {
828	    if (radeon_output->TMDSType == TMDS_INT) {
829		info->output_dfp1 &= ~(1 << o);
830		if (!info->output_dfp1) {
831		    tmp = INREG(RADEON_FP_GEN_CNTL);
832		    tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
833		    OUTREG(RADEON_FP_GEN_CNTL, tmp);
834		    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
835		    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
836			(info->ChipFamily == CHIP_FAMILY_RS480)) {
837			tmp = INREG(RS400_FP_2ND_GEN_CNTL);
838			tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
839			OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
840			save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON |
841						   RS400_TMDS_2ND_EN);
842		    }
843		}
844	    } else if (radeon_output->TMDSType == TMDS_EXT) {
845		info->output_dfp2 &= ~(1 << o);
846		if (!info->output_dfp2) {
847		    tmp = INREG(RADEON_FP2_GEN_CNTL);
848		    tmp |= RADEON_FP2_BLANK_EN;
849		    tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
850		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
851		    save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
852		    save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
853		    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
854			(info->ChipFamily == CHIP_FAMILY_RS480)) {
855			tmp = INREG(RS400_FP2_2_GEN_CNTL);
856			tmp |= RS400_FP2_2_BLANK_EN;
857			tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
858			OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
859			save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
860			save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN;
861		    }
862		}
863	    }
864	} else if (radeon_output->MonType == MT_LCD) {
865	    info->output_lcd1 &= ~(1 << o);
866	    if (!info->output_lcd1) {
867		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
868		if (info->IsMobility || info->IsIGP) {
869		    /* Asic bug, when turning off LVDS_ON, we have to make sure
870		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
871		    */
872		    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
873		}
874		tmp = INREG(RADEON_LVDS_GEN_CNTL);
875		tmp |= RADEON_LVDS_DISPLAY_DIS;
876		tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
877		OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
878		save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
879		save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
880		if (info->IsMobility || info->IsIGP) {
881		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
882		}
883	    }
884	} else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
885	    info->output_tv1 &= ~(1 << o);
886	    tv_dac_change = 2;
887	    if (!info->output_tv1) {
888		tmp = INREG(RADEON_TV_MASTER_CNTL);
889		tmp &= ~RADEON_TV_ON;
890		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
891		radeon_output->tv_on = FALSE;
892	    }
893	}
894    }
895
896    if (tv_dac_change) {
897	if (bEnable)
898	    info->tv_dac_enable_mask |= tv_dac_change;
899	else
900	    info->tv_dac_enable_mask &= ~tv_dac_change;
901
902	if (bEnable && info->tv_dac_enable_mask)
903	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
904	else if (!bEnable && info->tv_dac_enable_mask == 0)
905	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
906
907    }
908}
909
910void
911legacy_output_dpms(xf86OutputPtr output, int mode)
912{
913    switch(mode) {
914    case DPMSModeOn:
915	RADEONEnableDisplay(output, TRUE);
916	break;
917    case DPMSModeOff:
918    case DPMSModeSuspend:
919    case DPMSModeStandby:
920	RADEONEnableDisplay(output, FALSE);
921	break;
922    }
923}
924
925static void
926RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
927		      DisplayModePtr mode, BOOL IsPrimary)
928{
929    ScrnInfoPtr pScrn = output->scrn;
930    RADEONInfoPtr  info       = RADEONPTR(pScrn);
931    RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
932    RADEONOutputPrivatePtr radeon_output = output->driver_private;
933    int i;
934    uint32_t tmp = info->SavedReg->tmds_pll_cntl & 0xfffff;
935
936    for (i=0; i<4; i++) {
937	if (radeon_output->tmds_pll[i].freq == 0) break;
938	if ((uint32_t)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
939	    tmp = radeon_output->tmds_pll[i].value ;
940	    break;
941	}
942    }
943
944    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
945	if (tmp & 0xfff00000)
946	    save->tmds_pll_cntl = tmp;
947	else {
948	    save->tmds_pll_cntl = info->SavedReg->tmds_pll_cntl & 0xfff00000;
949	    save->tmds_pll_cntl |= tmp;
950	}
951    } else save->tmds_pll_cntl = tmp;
952
953    save->tmds_transmitter_cntl = info->SavedReg->tmds_transmitter_cntl &
954					~(RADEON_TMDS_TRANSMITTER_PLLRST);
955
956    if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
957	save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
958    else /* weird, RV chips got this bit reversed? */
959	save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
960
961    save->fp_gen_cntl = info->SavedReg->fp_gen_cntl |
962			 (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
963			  RADEON_FP_CRTC_DONT_SHADOW_HEND );
964
965    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
966
967    if (pScrn->rgbBits == 8)
968	save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT;  /* 24 bit format */
969    else
970	save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
971
972
973    if (IsPrimary) {
974	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
975	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
976	    if (radeon_output->Flags & RADEON_USE_RMX)
977		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
978	    else
979		save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
980	} else
981	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
982    } else {
983	if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
984	    save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
985	    save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
986	} else
987	    save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
988    }
989
990    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
991	(info->ChipFamily == CHIP_FAMILY_RS480)) {
992	save->tmds2_transmitter_cntl = info->SavedReg->tmds2_transmitter_cntl &
993	    ~(RS400_TMDS2_PLLRST);
994	save->tmds2_transmitter_cntl &= ~(RS400_TMDS2_PLLEN);
995
996	save->fp_2nd_gen_cntl = info->SavedReg->fp_2nd_gen_cntl;
997
998	if (pScrn->rgbBits == 8)
999	    save->fp_2nd_gen_cntl |= RS400_PANEL_FORMAT_2ND;  /* 24 bit format */
1000	else
1001	    save->fp_2nd_gen_cntl &= ~RS400_PANEL_FORMAT_2ND;/* 18 bit format */
1002
1003	save->fp_2nd_gen_cntl &= ~RS400_FP_2ND_SOURCE_SEL_MASK;
1004
1005	if (IsPrimary) {
1006	    if (radeon_output->Flags & RADEON_USE_RMX)
1007		save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_RMX;
1008	    else
1009		save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC1;
1010	} else
1011	    save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC2;
1012    }
1013
1014}
1015
1016static void
1017RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
1018		       DisplayModePtr mode, BOOL IsPrimary)
1019{
1020    ScrnInfoPtr pScrn = output->scrn;
1021    RADEONInfoPtr info = RADEONPTR(pScrn);
1022    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1023
1024    if (pScrn->rgbBits == 8)
1025	save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl |
1026				RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
1027    else
1028	save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
1029				~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
1030
1031    save->fp2_gen_cntl &= ~(RADEON_FP2_ON |
1032			    RADEON_FP2_DVO_EN |
1033			    RADEON_FP2_DVO_RATE_SEL_SDR);
1034
1035
1036    /* XXX: these may be oem specific */
1037    if (IS_R300_VARIANT) {
1038	save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
1039#if 0
1040	if (mode->Clock > 165000)
1041	    save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
1042#endif
1043    }
1044
1045    if (IsPrimary) {
1046	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
1047	    save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
1048	    if (radeon_output->Flags & RADEON_USE_RMX)
1049		save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
1050	    else
1051		save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
1052	} else {
1053	    save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
1054	}
1055    } else {
1056	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
1057	    save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
1058	    save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
1059	} else {
1060	    save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
1061	}
1062    }
1063
1064    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
1065	(info->ChipFamily == CHIP_FAMILY_RS480)) {
1066	if (pScrn->rgbBits == 8)
1067	    save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl |
1068		RS400_FP2_2_PANEL_FORMAT; /* 24 bit format, */
1069	else
1070	    save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl &
1071		~RS400_FP2_2_PANEL_FORMAT;/* 18 bit format, */
1072
1073	save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON |
1074				  RS400_FP2_2_DVO2_EN |
1075				  RS400_FP2_2_SOURCE_SEL_MASK);
1076
1077	if (IsPrimary) {
1078	    if (radeon_output->Flags & RADEON_USE_RMX)
1079		save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_RMX;
1080	    else
1081		save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC1;
1082	} else
1083	    save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC2;
1084    }
1085
1086}
1087
1088static void
1089RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
1090			DisplayModePtr mode, BOOL IsPrimary)
1091{
1092    ScrnInfoPtr pScrn = output->scrn;
1093    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1094    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1095
1096    save->lvds_pll_cntl = (info->SavedReg->lvds_pll_cntl |
1097			   RADEON_LVDS_PLL_EN);
1098
1099    save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
1100
1101    save->lvds_gen_cntl = info->SavedReg->lvds_gen_cntl;
1102    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
1103    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON |
1104			     RADEON_LVDS_BLON |
1105			     RADEON_LVDS_EN |
1106			     RADEON_LVDS_RST_FM);
1107
1108    if (IS_R300_VARIANT)
1109	save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
1110
1111    if (IsPrimary) {
1112	if (IS_R300_VARIANT) {
1113	    if (radeon_output->Flags & RADEON_USE_RMX)
1114		save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
1115	} else
1116	    save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
1117    } else {
1118	if (IS_R300_VARIANT) {
1119	    save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
1120	} else
1121	    save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
1122    }
1123
1124}
1125
1126static void
1127RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
1128		       DisplayModePtr mode)
1129{
1130    ScrnInfoPtr pScrn = output->scrn;
1131    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1132    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1133    int    xres = mode->HDisplay;
1134    int    yres = mode->VDisplay;
1135    Bool   Hscale = TRUE, Vscale = TRUE;
1136    int    hsync_wid;
1137    int    vsync_wid;
1138    int    hsync_start;
1139
1140
1141    save->fp_vert_stretch = info->SavedReg->fp_vert_stretch &
1142	                    (RADEON_VERT_STRETCH_RESERVED |
1143			     RADEON_VERT_AUTO_RATIO_INC);
1144    save->fp_horz_stretch = info->SavedReg->fp_horz_stretch &
1145	                    (RADEON_HORZ_FP_LOOP_STRETCH |
1146	                     RADEON_HORZ_AUTO_RATIO_INC);
1147
1148    save->crtc_more_cntl = 0;
1149    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
1150	(info->ChipFamily == CHIP_FAMILY_RS200)) {
1151	/* This is to workaround the asic bug for RMX, some versions
1152           of BIOS dosen't have this register initialized correctly.
1153	*/
1154	save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
1155    }
1156
1157
1158    save->fp_crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
1159				  | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
1160				     << 16));
1161
1162    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
1163    if (!hsync_wid)       hsync_wid = 1;
1164    hsync_start = mode->CrtcHSyncStart - 8;
1165
1166    save->fp_h_sync_strt_wid = ((hsync_start & 0x1fff)
1167				| ((hsync_wid & 0x3f) << 16)
1168				| ((mode->Flags & V_NHSYNC)
1169				   ? RADEON_CRTC_H_SYNC_POL
1170				   : 0));
1171
1172    save->fp_crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
1173				  | ((mode->CrtcVDisplay - 1) << 16));
1174
1175    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
1176    if (!vsync_wid)       vsync_wid = 1;
1177
1178    save->fp_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
1179				| ((vsync_wid & 0x1f) << 16)
1180				| ((mode->Flags & V_NVSYNC)
1181				   ? RADEON_CRTC_V_SYNC_POL
1182				   : 0));
1183
1184    save->fp_horz_vert_active = 0;
1185
1186    if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
1187	return;
1188
1189    if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
1190	Hscale = FALSE;
1191	Vscale = FALSE;
1192    } else {
1193	if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
1194	if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
1195
1196	if (xres == radeon_output->PanelXRes)
1197	    Hscale = FALSE;
1198	if (yres == radeon_output->PanelYRes)
1199	    Vscale = FALSE;
1200    }
1201
1202    if ((!Hscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
1203	(radeon_output->rmx_type == RMX_CENTER)) {
1204	save->fp_horz_stretch |= ((xres/8-1)<<16);
1205    } else {
1206	CARD32 scale, inc;
1207	inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
1208	scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
1209	    / radeon_output->PanelXRes + 1;
1210	save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
1211				  RADEON_HORZ_STRETCH_BLEND |
1212				  RADEON_HORZ_STRETCH_ENABLE |
1213				  ((radeon_output->PanelXRes/8-1)<<16));
1214    }
1215
1216    if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
1217	(radeon_output->rmx_type == RMX_CENTER)) {
1218	save->fp_vert_stretch |= ((yres-1)<<12);
1219    } else {
1220	CARD32 scale, inc;
1221	inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
1222	scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
1223	    / radeon_output->PanelYRes + 1;
1224	save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
1225				  RADEON_VERT_STRETCH_ENABLE |
1226				  RADEON_VERT_STRETCH_BLEND |
1227				  ((radeon_output->PanelYRes-1)<<12));
1228    }
1229
1230    if ((radeon_output->rmx_type == RMX_CENTER) &&
1231	(radeon_output->Flags & RADEON_USE_RMX)) {
1232	int    blank_width;
1233
1234	save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
1235				 RADEON_CRTC_AUTO_VERT_CENTER_EN);
1236
1237	blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8;
1238	if (blank_width > 110) blank_width = 110;
1239
1240	save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
1241				      | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
1242					 << 16));
1243
1244	hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
1245	if (!hsync_wid)       hsync_wid = 1;
1246
1247	save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff)
1248				    | ((hsync_wid & 0x3f) << 16)
1249				    | ((mode->Flags & V_NHSYNC)
1250				       ? RADEON_CRTC_H_SYNC_POL
1251				       : 0));
1252
1253	save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff)
1254				      | ((mode->CrtcVDisplay - 1) << 16));
1255
1256	vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
1257	if (!vsync_wid)       vsync_wid = 1;
1258
1259	save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff)
1260				    | ((vsync_wid & 0x1f) << 16)
1261				    | ((mode->Flags & V_NVSYNC)
1262				       ? RADEON_CRTC_V_SYNC_POL
1263				       : 0)));
1264
1265	save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) |
1266				     (((radeon_output->PanelXRes / 8) & 0x1ff) << 16));
1267
1268    }
1269}
1270
1271static void
1272RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
1273		       DisplayModePtr mode, BOOL IsPrimary)
1274{
1275    ScrnInfoPtr pScrn = output->scrn;
1276    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1277
1278    if (IsPrimary) {
1279	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
1280            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
1281					~RADEON_DISP_DAC_SOURCE_MASK;
1282        } else {
1283            save->dac2_cntl = info->SavedReg->dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
1284        }
1285    } else {
1286        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
1287            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
1288					~RADEON_DISP_DAC_SOURCE_MASK;
1289            save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
1290        } else {
1291            save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
1292        }
1293    }
1294    save->dac_cntl = (RADEON_DAC_MASK_ALL
1295		      | RADEON_DAC_VGA_ADR_EN
1296		      | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
1297
1298    save->dac_macro_cntl = info->SavedReg->dac_macro_cntl;
1299}
1300
1301static void
1302RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
1303{
1304    ScrnInfoPtr pScrn = output->scrn;
1305    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1306    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1307
1308    if (info->ChipFamily == CHIP_FAMILY_R420 ||
1309	info->ChipFamily == CHIP_FAMILY_RV410) {
1310	save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
1311			     ~(RADEON_TV_DAC_STD_MASK |
1312			       RADEON_TV_DAC_BGADJ_MASK |
1313			       R420_TV_DAC_DACADJ_MASK |
1314			       R420_TV_DAC_RDACPD |
1315			       R420_TV_DAC_GDACPD |
1316			       R420_TV_DAC_GDACPD |
1317			       R420_TV_DAC_TVENABLE);
1318    } else {
1319	save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
1320			     ~(RADEON_TV_DAC_STD_MASK |
1321			       RADEON_TV_DAC_BGADJ_MASK |
1322			       RADEON_TV_DAC_DACADJ_MASK |
1323			       RADEON_TV_DAC_RDACPD |
1324			       RADEON_TV_DAC_GDACPD |
1325			       RADEON_TV_DAC_GDACPD);
1326    }
1327
1328    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
1329			  RADEON_TV_DAC_NHOLD |
1330			  RADEON_TV_DAC_STD_PS2 |
1331			  radeon_output->ps2_tvdac_adj);
1332
1333}
1334
1335static void
1336RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
1337			DisplayModePtr mode, BOOL IsPrimary)
1338{
1339    ScrnInfoPtr pScrn = output->scrn;
1340    RADEONInfoPtr  info       = RADEONPTR(pScrn);
1341
1342    /*0x0028023;*/
1343    RADEONInitTvDacCntl(output, save);
1344
1345    if (IS_R300_VARIANT)
1346	save->gpiopad_a = info->SavedReg->gpiopad_a | 1;
1347
1348    save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
1349
1350    if (IsPrimary) {
1351        if (IS_R300_VARIANT) {
1352            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
1353					~RADEON_DISP_TVDAC_SOURCE_MASK;
1354            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
1355        } else if (info->ChipFamily == CHIP_FAMILY_R200) {
1356	    save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
1357				  ~(R200_FP2_SOURCE_SEL_MASK |
1358				    RADEON_FP2_DVO_RATE_SEL_SDR);
1359	} else {
1360            save->disp_hw_debug = info->SavedReg->disp_hw_debug | RADEON_CRT2_DISP1_SEL;
1361        }
1362    } else {
1363        if (IS_R300_VARIANT) {
1364            save->disp_output_cntl = info->SavedReg->disp_output_cntl &
1365					~RADEON_DISP_TVDAC_SOURCE_MASK;
1366            save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
1367	} else if (info->ChipFamily == CHIP_FAMILY_R200) {
1368	    save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
1369				  ~(R200_FP2_SOURCE_SEL_MASK |
1370				    RADEON_FP2_DVO_RATE_SEL_SDR);
1371            save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
1372        } else {
1373            save->disp_hw_debug = info->SavedReg->disp_hw_debug &
1374					~RADEON_CRT2_DISP1_SEL;
1375        }
1376    }
1377}
1378
1379static void
1380RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
1381			  DisplayModePtr mode, xf86OutputPtr output,
1382			  int crtc_num)
1383{
1384    Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
1385    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1386    RADEONInfoPtr info = RADEONPTR(pScrn);
1387
1388    if (crtc_num == 0)
1389	RADEONInitRMXRegisters(output, save, mode);
1390
1391    if (radeon_output->MonType == MT_CRT) {
1392	if (radeon_output->DACType == DAC_PRIMARY) {
1393	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
1394	} else {
1395	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
1396	    /* IGP chips seem to use a mix of primary and TVDAC controls */
1397	    if (info->IsIGP)
1398		RADEONInitDACRegisters(output, save, mode, IsPrimary);
1399	}
1400    } else if (radeon_output->MonType == MT_LCD) {
1401	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
1402    } else if (radeon_output->MonType == MT_DFP) {
1403	if (radeon_output->TMDSType == TMDS_INT) {
1404	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
1405	} else {
1406	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
1407	}
1408    } else if (radeon_output->MonType == MT_STV ||
1409	       radeon_output->MonType == MT_CTV) {
1410	RADEONInitTVRegisters(output, save, mode, IsPrimary);
1411    }
1412}
1413
1414void
1415legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
1416		  DisplayModePtr adjusted_mode)
1417{
1418    ScrnInfoPtr	    pScrn = output->scrn;
1419    RADEONInfoPtr info = RADEONPTR(pScrn);
1420    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1421    xf86CrtcPtr	crtc = output->crtc;
1422    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
1423
1424    RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
1425
1426    if (radeon_crtc->crtc_id == 0)
1427	RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
1428
1429    switch(radeon_output->MonType) {
1430    case MT_LCD:
1431	ErrorF("restore LVDS\n");
1432	RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
1433	break;
1434    case MT_DFP:
1435	if (radeon_output->TMDSType == TMDS_INT) {
1436	    ErrorF("restore FP\n");
1437	    RADEONRestoreFPRegisters(pScrn, info->ModeReg);
1438	} else {
1439	    ErrorF("restore FP2\n");
1440	    if (info->IsAtomBios) {
1441		unsigned char *RADEONMMIO = info->MMIO;
1442		uint32_t fp2_gen_cntl;
1443
1444		atombios_external_tmds_setup(output, mode);
1445		/* r4xx atom has hard coded crtc mappings in the atom code
1446		 * Fix it up here.
1447		 */
1448		fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK;
1449		if (radeon_crtc->crtc_id == 1)
1450		    fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
1451		else {
1452		    if (radeon_output->Flags & RADEON_USE_RMX)
1453			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
1454		    else
1455			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
1456		}
1457		OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
1458	    } else {
1459		RADEONRestoreDVOChip(pScrn, output);
1460		RADEONRestoreFP2Registers(pScrn, info->ModeReg);
1461	    }
1462	}
1463	break;
1464    case MT_STV:
1465    case MT_CTV:
1466	ErrorF("restore tv\n");
1467	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
1468	RADEONRestoreTVRegisters(pScrn, info->ModeReg);
1469	break;
1470    default:
1471	ErrorF("restore dac\n");
1472	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
1473    }
1474
1475}
1476
1477/* the following functions are based on the load detection code
1478 * in the beos radeon driver by Thomas Kurschel and the existing
1479 * load detection code in this driver.
1480 */
1481static RADEONMonitorType
1482radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
1483{
1484    RADEONInfoPtr info = RADEONPTR(pScrn);
1485    unsigned char *RADEONMMIO = info->MMIO;
1486    uint32_t vclk_ecp_cntl, crtc_ext_cntl;
1487    uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
1488    RADEONMonitorType found = MT_NONE;
1489
1490    /* save the regs we need */
1491    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
1492    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
1493    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
1494    dac_cntl = INREG(RADEON_DAC_CNTL);
1495    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
1496
1497    tmp = vclk_ecp_cntl &
1498	~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
1499    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
1500
1501    tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
1502    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
1503
1504    tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
1505	RADEON_DAC_FORCE_DATA_EN;
1506
1507    if (color)
1508	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
1509    else
1510	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
1511
1512    if (IS_R300_VARIANT)
1513	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
1514    else
1515	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
1516
1517    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
1518
1519    tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
1520    tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
1521    OUTREG(RADEON_DAC_CNTL, tmp);
1522
1523    tmp &= ~(RADEON_DAC_PDWN_R |
1524	     RADEON_DAC_PDWN_G |
1525	     RADEON_DAC_PDWN_B);
1526
1527    OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
1528
1529    usleep(2000);
1530
1531    if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
1532	found = MT_CRT;
1533	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1534		    "Found %s CRT connected to primary DAC\n",
1535		    color ? "color" : "bw");
1536    }
1537
1538    /* restore the regs we used */
1539    OUTREG(RADEON_DAC_CNTL, dac_cntl);
1540    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
1541    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
1542    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
1543    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
1544
1545    return found;
1546}
1547
1548static RADEONMonitorType
1549radeon_detect_ext_dac(ScrnInfoPtr pScrn)
1550{
1551    RADEONInfoPtr info = RADEONPTR(pScrn);
1552    unsigned char *RADEONMMIO = info->MMIO;
1553    uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
1554    uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
1555    uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
1556    uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
1557    uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
1558    RADEONMonitorType found = MT_NONE;
1559    int connected = 0;
1560    int i = 0;
1561
1562    /* save the regs we need */
1563    gpio_monid = INREG(RADEON_GPIO_MONID);
1564    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
1565    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
1566    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
1567    disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
1568    disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
1569    disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
1570    disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
1571    disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
1572    disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
1573    crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
1574    crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
1575    crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
1576    crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
1577
1578    tmp = INREG(RADEON_GPIO_MONID);
1579    tmp &= ~RADEON_GPIO_A_0;
1580    OUTREG(RADEON_GPIO_MONID, tmp);
1581
1582    OUTREG(RADEON_FP2_GEN_CNTL,
1583	   RADEON_FP2_ON |
1584	   RADEON_FP2_PANEL_FORMAT |
1585	   R200_FP2_SOURCE_SEL_TRANS_UNIT |
1586	   RADEON_FP2_DVO_EN |
1587	   R200_FP2_DVO_RATE_SEL_SDR);
1588
1589    OUTREG(RADEON_DISP_OUTPUT_CNTL,
1590	   RADEON_DISP_DAC_SOURCE_RMX |
1591	   RADEON_DISP_TRANS_MATRIX_GRAPHICS);
1592
1593    OUTREG(RADEON_CRTC2_GEN_CNTL,
1594	   RADEON_CRTC2_EN |
1595	   RADEON_CRTC2_DISP_REQ_EN_B);
1596
1597    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
1598    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
1599    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
1600    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
1601    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
1602    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
1603
1604    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
1605    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
1606    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
1607    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
1608
1609    for (i = 0; i < 200; i++) {
1610	tmp = INREG(RADEON_GPIO_MONID);
1611	if (tmp & RADEON_GPIO_Y_0)
1612	    connected = 1;
1613	else
1614	    connected = 0;
1615
1616	if (!connected)
1617	    break;
1618
1619	usleep(1000);
1620    }
1621
1622    if (connected)
1623	found = MT_CRT;
1624
1625    /* restore the regs we used */
1626    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
1627    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
1628    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
1629    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
1630    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
1631    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
1632    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
1633    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
1634    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
1635    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
1636    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
1637    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
1638    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
1639    OUTREG(RADEON_GPIO_MONID, gpio_monid);
1640
1641    return found;
1642}
1643
1644static RADEONMonitorType
1645radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
1646{
1647    RADEONInfoPtr info = RADEONPTR(pScrn);
1648    unsigned char *RADEONMMIO = info->MMIO;
1649    uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
1650    uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
1651    RADEONMonitorType found = MT_NONE;
1652
1653    /* save the regs we need */
1654    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
1655    gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
1656    disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
1657    disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
1658    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
1659    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
1660    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
1661    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
1662
1663    tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
1664			   | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
1665    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
1666
1667    if (IS_R300_VARIANT) {
1668	OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
1669    }
1670
1671    tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
1672    tmp |= RADEON_CRTC2_CRT2_ON |
1673	(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
1674
1675    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
1676
1677    if (IS_R300_VARIANT) {
1678	tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
1679	tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
1680	OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
1681    } else {
1682	tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
1683	OUTREG(RADEON_DISP_HW_DEBUG, tmp);
1684    }
1685
1686    tmp = RADEON_TV_DAC_NBLANK |
1687	RADEON_TV_DAC_NHOLD |
1688	RADEON_TV_MONITOR_DETECT_EN |
1689	RADEON_TV_DAC_STD_PS2;
1690
1691    OUTREG(RADEON_TV_DAC_CNTL, tmp);
1692
1693    tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
1694	RADEON_DAC2_FORCE_DATA_EN;
1695
1696    if (color)
1697	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
1698    else
1699	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
1700
1701    if (IS_R300_VARIANT)
1702	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
1703    else
1704	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
1705
1706    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
1707
1708    tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
1709    OUTREG(RADEON_DAC_CNTL2, tmp);
1710
1711    usleep(10000);
1712
1713    if (IS_R300_VARIANT) {
1714	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
1715	    found = MT_CRT;
1716	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1717			"Found %s CRT connected to TV DAC\n",
1718			color ? "color" : "bw");
1719	}
1720    } else {
1721	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
1722	    found = MT_CRT;
1723	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1724			"Found %s CRT connected to TV DAC\n",
1725			color ? "color" : "bw");
1726	}
1727    }
1728
1729    /* restore regs we used */
1730    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
1731    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
1732    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1733    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
1734
1735    if (IS_R300_VARIANT) {
1736	OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
1737	OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
1738    } else {
1739	OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
1740    }
1741    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
1742
1743    return found;
1744}
1745
1746static RADEONMonitorType
1747r300_detect_tv(ScrnInfoPtr pScrn)
1748{
1749    RADEONInfoPtr info = RADEONPTR(pScrn);
1750    unsigned char *RADEONMMIO = info->MMIO;
1751    uint32_t tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
1752    uint32_t gpiopad_a, disp_output_cntl;
1753    RADEONMonitorType found = MT_NONE;
1754
1755    /* save the regs we need */
1756    gpiopad_a = INREG(RADEON_GPIOPAD_A);
1757    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
1758    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
1759    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
1760    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
1761    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
1762
1763    OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
1764
1765    OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
1766
1767    OUTREG(RADEON_CRTC2_GEN_CNTL,
1768	   RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
1769
1770    tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
1771    tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
1772    OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
1773
1774    OUTREG(RADEON_DAC_EXT_CNTL,
1775	   RADEON_DAC2_FORCE_BLANK_OFF_EN |
1776	   RADEON_DAC2_FORCE_DATA_EN |
1777	   RADEON_DAC_FORCE_DATA_SEL_RGB |
1778	   (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
1779
1780    OUTREG(RADEON_TV_DAC_CNTL,
1781	   RADEON_TV_DAC_STD_NTSC |
1782	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
1783	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
1784
1785    INREG(RADEON_TV_DAC_CNTL);
1786
1787    usleep(4000);
1788
1789    OUTREG(RADEON_TV_DAC_CNTL,
1790	   RADEON_TV_DAC_NBLANK |
1791	   RADEON_TV_DAC_NHOLD |
1792	   RADEON_TV_MONITOR_DETECT_EN |
1793	   RADEON_TV_DAC_STD_NTSC |
1794	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
1795	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
1796
1797    INREG(RADEON_TV_DAC_CNTL);
1798
1799    usleep(6000);
1800
1801    tmp = INREG(RADEON_TV_DAC_CNTL);
1802    if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
1803	found = MT_STV;
1804	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1805		    "S-Video TV connection detected\n");
1806    } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
1807	found = MT_CTV;
1808	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1809		    "Composite TV connection detected\n" );
1810    }
1811
1812    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
1813    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
1814    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
1815    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
1816    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
1817    OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
1818
1819    return found;
1820}
1821
1822static RADEONMonitorType
1823radeon_detect_tv(ScrnInfoPtr pScrn)
1824{
1825    RADEONInfoPtr info = RADEONPTR(pScrn);
1826    unsigned char *RADEONMMIO = info->MMIO;
1827    uint32_t tmp, dac_cntl2, tv_master_cntl;
1828    uint32_t tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
1829    RADEONMonitorType found = MT_NONE;
1830
1831    if (IS_R300_VARIANT)
1832	return r300_detect_tv(pScrn);
1833
1834    /* save the regs we need */
1835    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
1836    tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
1837    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
1838    config_cntl = INREG(RADEON_CONFIG_CNTL);
1839    tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
1840
1841    tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
1842    OUTREG(RADEON_DAC_CNTL2, tmp);
1843
1844    tmp = tv_master_cntl | RADEON_TV_ON;
1845    tmp &= ~(RADEON_TV_ASYNC_RST |
1846	     RADEON_RESTART_PHASE_FIX |
1847	     RADEON_CRT_FIFO_CE_EN |
1848	     RADEON_TV_FIFO_CE_EN |
1849	     RADEON_RE_SYNC_NOW_SEL_MASK);
1850    tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
1851
1852    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
1853
1854    tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
1855	RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
1856	(8 << RADEON_TV_DAC_BGADJ_SHIFT);
1857
1858    if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
1859	tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
1860    else
1861	tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
1862
1863    OUTREG(RADEON_TV_DAC_CNTL, tmp);
1864
1865    tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
1866	RADEON_RED_MX_FORCE_DAC_DATA |
1867	RADEON_GRN_MX_FORCE_DAC_DATA |
1868	RADEON_BLU_MX_FORCE_DAC_DATA |
1869	(0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
1870
1871    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
1872
1873    usleep(3000);
1874
1875    tmp = INREG(RADEON_TV_DAC_CNTL);
1876    if (tmp & RADEON_TV_DAC_GDACDET) {
1877	found = MT_STV;
1878	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1879		    "S-Video TV connection detected\n");
1880    } else if (tmp & RADEON_TV_DAC_BDACDET) {
1881	found = MT_CTV;
1882	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
1883		    "Composite TV connection detected\n" );
1884    }
1885
1886    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
1887    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1888    OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
1889    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
1890
1891    return found;
1892}
1893