atombios_output.c revision 921a55d8
1/*
2 * Copyright © 2007 Red Hat, Inc.
3 * Copyright 2007  Advanced Micro Devices, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 *    Dave Airlie <airlied@redhat.com>
26 *    Alex Deucher <alexdeucher@gmail.com>
27 *
28 */
29
30/*
31 * avivo output handling functions.
32 */
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36/* DPMS */
37#ifdef HAVE_XEXTPROTO_71
38#include <X11/extensions/dpmsconst.h>
39#else
40#define DPMS_SERVER
41#include <X11/extensions/dpms.h>
42#endif
43
44#include <unistd.h>
45
46#include "radeon.h"
47#include "radeon_reg.h"
48#include "radeon_macros.h"
49#include "radeon_atombios.h"
50
51#include "ati_pciids_gen.h"
52
53const char *device_name[12] = {
54    "CRT1",
55    "LCD1",
56    "TV1",
57    "DFP1",
58    "CRT2",
59    "LCD2",
60    "TV2",
61    "DFP2",
62    "CV",
63    "DFP3",
64    "DFP4",
65    "DFP5",
66};
67
68#define AUX_NATIVE_WRITE                    0x8
69#define AUX_NATIVE_READ                     0x9
70
71#define AUX_I2C_WRITE                       0x0
72#define AUX_I2C_READ                        0x1
73#define AUX_I2C_STATUS                      0x2
74#define AUX_I2C_MOT                         0x4
75
76#define DP_DPCD_REV                         0x0
77#define DP_MAX_LINK_RATE                    0x1
78#define DP_MAX_LANE_COUNT                   0x2
79#define DP_MAX_DOWNSPREAD                   0x3
80#define DP_NORP                             0x4
81#define DP_DOWNSTREAMPORT_PRESENT           0x5
82#define DP_MAIN_LINK_CHANNEL_CONFIG         0x6
83#define DP_DP11_DOWNSTREAM_PORT_COUNT       0x7
84
85/* from intel i830_dp.h */
86#define DP_LINK_BW_SET                      0x100
87//# define DP_LINK_BW_1_62                    0x06
88//# define DP_LINK_BW_2_7                     0x0a
89#define DP_LANE_COUNT_SET                   0x101
90# define DP_LANE_COUNT_MASK                 0x0f
91# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
92
93#define DP_TRAINING_PATTERN_SET             0x102
94
95# define DP_TRAINING_PATTERN_DISABLE        0
96# define DP_TRAINING_PATTERN_1              1
97# define DP_TRAINING_PATTERN_2              2
98# define DP_TRAINING_PATTERN_MASK           0x3
99
100# define DP_LINK_QUAL_PATTERN_DISABLE       (0 << 2)
101# define DP_LINK_QUAL_PATTERN_D10_2         (1 << 2)
102# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
103# define DP_LINK_QUAL_PATTERN_PRBS7         (3 << 2)
104# define DP_LINK_QUAL_PATTERN_MASK          (3 << 2)
105# define DP_RECOVERED_CLOCK_OUT_EN          (1 << 4)
106# define DP_LINK_SCRAMBLING_DISABLE         (1 << 5)
107
108# define DP_SYMBOL_ERROR_COUNT_BOTH         (0 << 6)
109# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
110# define DP_SYMBOL_ERROR_COUNT_SYMBOL       (2 << 6)
111# define DP_SYMBOL_ERROR_COUNT_MASK         (3 << 6)
112
113#define DP_TRAINING_LANE0_SET               0x103
114#define DP_TRAINING_LANE1_SET               0x104
115#define DP_TRAINING_LANE2_SET               0x105
116#define DP_TRAINING_LANE3_SET               0x106
117# define DP_TRAIN_VOLTAGE_SWING_MASK        0x3
118# define DP_TRAIN_VOLTAGE_SWING_SHIFT       0
119# define DP_TRAIN_MAX_SWING_REACHED         (1 << 2)
120# define DP_TRAIN_VOLTAGE_SWING_400         (0 << 0)
121# define DP_TRAIN_VOLTAGE_SWING_600         (1 << 0)
122# define DP_TRAIN_VOLTAGE_SWING_800         (2 << 0)
123# define DP_TRAIN_VOLTAGE_SWING_1200        (3 << 0)
124
125# define DP_TRAIN_PRE_EMPHASIS_MASK         (3 << 3)
126# define DP_TRAIN_PRE_EMPHASIS_0            (0 << 3)
127# define DP_TRAIN_PRE_EMPHASIS_3_5          (1 << 3)
128# define DP_TRAIN_PRE_EMPHASIS_6            (2 << 3)
129# define DP_TRAIN_PRE_EMPHASIS_9_5          (3 << 3)
130
131# define DP_TRAIN_PRE_EMPHASIS_SHIFT        3
132# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
133#define DP_DOWNSPREAD_CTRL                  0x107
134# define DP_SPREAD_AMP_0_5                  (1 << 4)
135
136#define DP_MAIN_LINK_CHANNEL_CODING_SET     0x108
137# define DP_SET_ANSI_8B10B                  (1 << 0)
138
139#define DP_LANE0_1_STATUS                   0x202
140#define DP_LANE2_3_STATUS                   0x203
141
142# define DP_LANE_CR_DONE                    (1 << 0)
143# define DP_LANE_CHANNEL_EQ_DONE            (1 << 1)
144# define DP_LANE_SYMBOL_LOCKED              (1 << 2)
145
146#define DP_LANE_ALIGN_STATUS_UPDATED        0x204
147#define DP_INTERLANE_ALIGN_DONE             (1 << 0)
148#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
149#define DP_LINK_STATUS_UPDATED              (1 << 7)
150
151#define DP_SINK_STATUS                      0x205
152
153#define DP_RECEIVE_PORT_0_STATUS            (1 << 0)
154#define DP_RECEIVE_PORT_1_STATUS            (1 << 1)
155
156#define DP_ADJUST_REQUEST_LANE0_1           0x206
157#define DP_ADJUST_REQUEST_LANE2_3           0x207
158
159#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
160#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
161#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
162#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
163#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
164#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
165#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
166#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
167
168#define DP_LINK_STATUS_SIZE                 6
169#define DP_LINK_CONFIGURATION_SIZE          9
170
171#define DP_SET_POWER_D0  0x1
172#define DP_SET_POWER_D3  0x2
173
174static void do_displayport_link_train(xf86OutputPtr output);
175static void atombios_pick_dig_encoder(xf86OutputPtr output);
176
177static int
178atombios_output_dac_setup(xf86OutputPtr output, int action)
179{
180    RADEONOutputPrivatePtr radeon_output = output->driver_private;
181    RADEONInfoPtr info       = RADEONPTR(output->scrn);
182    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
183    radeon_tvout_ptr tvout = &radeon_output->tvout;
184    DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
185    AtomBiosArgRec data;
186    unsigned char *space;
187    int index = 0, num = 0;
188    int clock = radeon_output->pixel_clock;
189
190    if (radeon_encoder == NULL)
191	return ATOM_NOT_IMPLEMENTED;
192
193    memset(&disp_data,0, sizeof(disp_data));
194
195    switch (radeon_encoder->encoder_id) {
196    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
197    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
198	index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
199	num = 1;
200	break;
201    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
202    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
203	index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
204	num = 2;
205	break;
206    }
207
208    disp_data.ucAction =action;
209
210    if (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT))
211	disp_data.ucDacStandard = ATOM_DAC1_PS2;
212    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
213	disp_data.ucDacStandard = ATOM_DAC1_CV;
214    else {
215	switch (tvout->tvStd) {
216	case TV_STD_PAL:
217	case TV_STD_PAL_M:
218	case TV_STD_SCART_PAL:
219	case TV_STD_SECAM:
220	case TV_STD_PAL_CN:
221	    disp_data.ucDacStandard = ATOM_DAC1_PAL;
222	    break;
223	case TV_STD_NTSC:
224	case TV_STD_NTSC_J:
225	case TV_STD_PAL_60:
226	default:
227	    disp_data.ucDacStandard = ATOM_DAC1_NTSC;
228	    break;
229	}
230    }
231    disp_data.usPixelClock = cpu_to_le16(clock / 10);
232
233    data.exec.index = index;
234    data.exec.dataSpace = (void *)&space;
235    data.exec.pspace = &disp_data;
236
237    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
238	ErrorF("Output DAC%d setup success\n", num);
239	return ATOM_SUCCESS;
240    }
241
242    ErrorF("Output DAC%d setup failed\n", num);
243    return ATOM_NOT_IMPLEMENTED;
244
245}
246
247static int
248atombios_output_tv_setup(xf86OutputPtr output, int action)
249{
250    RADEONOutputPrivatePtr radeon_output = output->driver_private;
251    radeon_tvout_ptr tvout = &radeon_output->tvout;
252    RADEONInfoPtr info       = RADEONPTR(output->scrn);
253    TV_ENCODER_CONTROL_PS_ALLOCATION disp_data;
254    AtomBiosArgRec data;
255    unsigned char *space;
256    int clock = radeon_output->pixel_clock;
257
258    memset(&disp_data,0, sizeof(disp_data));
259
260    disp_data.sTVEncoder.ucAction = action;
261
262    if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
263	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
264    else {
265	switch (tvout->tvStd) {
266	case TV_STD_NTSC:
267	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
268	    break;
269	case TV_STD_PAL:
270	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
271	    break;
272	case TV_STD_PAL_M:
273	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
274	    break;
275	case TV_STD_PAL_60:
276	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
277	    break;
278	case TV_STD_NTSC_J:
279	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
280	    break;
281	case TV_STD_SCART_PAL:
282	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
283	    break;
284	case TV_STD_SECAM:
285	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
286	    break;
287	case TV_STD_PAL_CN:
288	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
289	    break;
290	default:
291	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
292	    break;
293	}
294    }
295
296    disp_data.sTVEncoder.usPixelClock = cpu_to_le16(clock / 10);
297    data.exec.index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
298    data.exec.dataSpace = (void *)&space;
299    data.exec.pspace = &disp_data;
300
301    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
302	ErrorF("Output TV setup success\n");
303	return ATOM_SUCCESS;
304    }
305
306    ErrorF("Output TV setup failed\n");
307    return ATOM_NOT_IMPLEMENTED;
308
309}
310
311int
312atombios_external_tmds_setup(xf86OutputPtr output, int action)
313{
314    RADEONOutputPrivatePtr radeon_output = output->driver_private;
315    ScrnInfoPtr pScrn = output->scrn;
316    RADEONInfoPtr info       = RADEONPTR(pScrn);
317    ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION disp_data;
318    AtomBiosArgRec data;
319    unsigned char *space;
320    int clock = radeon_output->pixel_clock;
321
322    memset(&disp_data,0, sizeof(disp_data));
323
324    disp_data.sXTmdsEncoder.ucEnable = action;
325
326    if (clock > 165000)
327	disp_data.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
328
329    if (pScrn->rgbBits == 8)
330	disp_data.sXTmdsEncoder.ucMisc |= (1 << 1);
331
332    data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
333    data.exec.dataSpace = (void *)&space;
334    data.exec.pspace = &disp_data;
335
336    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
337	ErrorF("External TMDS setup success\n");
338	return ATOM_SUCCESS;
339    }
340
341    ErrorF("External TMDS setup failed\n");
342    return ATOM_NOT_IMPLEMENTED;
343}
344
345static int
346atombios_output_ddia_setup(xf86OutputPtr output, int action)
347{
348    RADEONOutputPrivatePtr radeon_output = output->driver_private;
349    RADEONInfoPtr info       = RADEONPTR(output->scrn);
350    DVO_ENCODER_CONTROL_PS_ALLOCATION disp_data;
351    AtomBiosArgRec data;
352    unsigned char *space;
353    int clock = radeon_output->pixel_clock;
354
355    memset(&disp_data,0, sizeof(disp_data));
356
357    disp_data.sDVOEncoder.ucAction = action;
358    disp_data.sDVOEncoder.usPixelClock = cpu_to_le16(clock / 10);
359
360    if (clock > 165000)
361	disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
362
363    data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
364    data.exec.dataSpace = (void *)&space;
365    data.exec.pspace = &disp_data;
366
367    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
368	ErrorF("DDIA setup success\n");
369	return ATOM_SUCCESS;
370    }
371
372    ErrorF("DDIA setup failed\n");
373    return ATOM_NOT_IMPLEMENTED;
374}
375
376static int
377atombios_output_digital_setup(xf86OutputPtr output, int action)
378{
379    RADEONOutputPrivatePtr radeon_output = output->driver_private;
380    ScrnInfoPtr pScrn = output->scrn;
381    RADEONInfoPtr info       = RADEONPTR(pScrn);
382    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
383    LVDS_ENCODER_CONTROL_PS_ALLOCATION disp_data;
384    LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 disp_data2;
385    AtomBiosArgRec data;
386    unsigned char *space;
387    int index = 0;
388    int major, minor;
389    int lvds_misc = 0;
390    int clock = radeon_output->pixel_clock;
391
392    if (radeon_encoder == NULL)
393	return ATOM_NOT_IMPLEMENTED;
394
395    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
396	radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
397	if (lvds == NULL)
398	    return ATOM_NOT_IMPLEMENTED;
399	lvds_misc = lvds->lvds_misc;
400    }
401
402    memset(&disp_data,0, sizeof(disp_data));
403    memset(&disp_data2,0, sizeof(disp_data2));
404
405    switch (radeon_encoder->encoder_id) {
406    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
407	index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
408	break;
409    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
410    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
411	index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
412	break;
413    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
414    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
415	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
416	    index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
417	else
418	    index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
419	break;
420    }
421
422    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
423
424    /*ErrorF("table is %d %d\n", major, minor);*/
425    switch (major) {
426    case 0:
427    case 1:
428    case 2:
429	switch (minor) {
430	case 1:
431	    disp_data.ucMisc = 0;
432	    disp_data.ucAction = action;
433	    if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
434		(radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B))
435		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
436	    disp_data.usPixelClock = cpu_to_le16(clock / 10);
437	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
438		if (lvds_misc & (1 << 0))
439		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
440		if (lvds_misc & (1 << 1))
441		    disp_data.ucMisc |= (1 << 1);
442	    } else {
443		if (radeon_output->linkb)
444		    disp_data.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
445		if (clock > 165000)
446		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
447		if (pScrn->rgbBits == 8)
448		    disp_data.ucMisc |= (1 << 1);
449	    }
450	    data.exec.pspace = &disp_data;
451	    break;
452	case 2:
453	case 3:
454	    disp_data2.ucMisc = 0;
455	    disp_data2.ucAction = action;
456	    if (minor == 3) {
457		if (radeon_output->coherent_mode) {
458		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
459		    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Coherent Mode enabled\n");
460		}
461	    }
462	    if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
463		(radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B))
464		disp_data2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
465	    disp_data2.usPixelClock = cpu_to_le16(clock / 10);
466	    disp_data2.ucTruncate = 0;
467	    disp_data2.ucSpatial = 0;
468	    disp_data2.ucTemporal = 0;
469	    disp_data2.ucFRC = 0;
470	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
471		if (lvds_misc & (1 << 0))
472		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
473		if (lvds_misc & (1 << 5)) {
474		    disp_data2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
475		    if (lvds_misc & (1 << 1))
476			disp_data2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
477		}
478		if (lvds_misc & (1 << 6)) {
479		    disp_data2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
480		    if (lvds_misc & (1 << 1))
481			disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
482		    if (((lvds_misc >> 2) & 0x3) == 2)
483			disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
484		}
485	    } else {
486		if (radeon_output->linkb)
487		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
488		if (clock > 165000)
489		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
490	    }
491	    data.exec.pspace = &disp_data2;
492	    break;
493	default:
494	    ErrorF("Unknown table version\n");
495	    exit(-1);
496	}
497	break;
498    default:
499	ErrorF("Unknown table version\n");
500	exit(-1);
501    }
502
503    data.exec.index = index;
504    data.exec.dataSpace = (void *)&space;
505
506    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
507	ErrorF("Output digital setup success\n");
508	return ATOM_SUCCESS;
509    }
510
511    ErrorF("Output digital setup failed\n");
512    return ATOM_NOT_IMPLEMENTED;
513}
514
515static int
516atombios_maybe_hdmi_mode(xf86OutputPtr output)
517{
518#ifndef EDID_COMPLETE_RAWDATA
519    /* there's no getting this right unless we have complete EDID */
520    return ATOM_ENCODER_MODE_DVI;
521#else
522    if (output && xf86MonitorIsHDMI(output->MonInfo))
523	return ATOM_ENCODER_MODE_HDMI;
524
525    return ATOM_ENCODER_MODE_DVI;
526#endif
527}
528
529int
530atombios_get_encoder_mode(xf86OutputPtr output)
531{
532    ScrnInfoPtr pScrn = output->scrn;
533    RADEONInfoPtr info       = RADEONPTR(pScrn);
534    RADEONOutputPrivatePtr radeon_output = output->driver_private;
535
536    /* DVI should really be atombios_maybe_hdmi_mode() as well */
537    switch (radeon_output->ConnectorType) {
538    case CONNECTOR_DVI_I:
539	if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))
540	    return ATOM_ENCODER_MODE_DVI;
541	else
542	    return ATOM_ENCODER_MODE_CRT;
543	break;
544    case CONNECTOR_DVI_D:
545    default:
546	return ATOM_ENCODER_MODE_DVI;
547	break;
548    case CONNECTOR_HDMI_TYPE_A:
549    case CONNECTOR_HDMI_TYPE_B:
550	if (IS_DCE4_VARIANT)
551	    return ATOM_ENCODER_MODE_DVI;
552	else
553	    return atombios_maybe_hdmi_mode(output);
554	break;
555    case CONNECTOR_LVDS:
556	return ATOM_ENCODER_MODE_LVDS;
557	break;
558    case CONNECTOR_DISPLAY_PORT:
559    case CONNECTOR_EDP:
560	if (radeon_output->MonType == MT_DP)
561	    return ATOM_ENCODER_MODE_DP;
562	else {
563	    if (IS_DCE4_VARIANT)
564	        return ATOM_ENCODER_MODE_DVI;
565	    else
566	        return atombios_maybe_hdmi_mode(output);
567	}
568	break;
569    case CONNECTOR_DVI_A:
570    case CONNECTOR_VGA:
571    case CONNECTOR_STV:
572    case CONNECTOR_CTV:
573    case CONNECTOR_DIN:
574	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
575	    return ATOM_ENCODER_MODE_TV;
576	else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
577	    return ATOM_ENCODER_MODE_CV;
578	else
579	    return ATOM_ENCODER_MODE_CRT;
580	break;
581    }
582
583}
584
585static const int dp_clocks[] = {
586    5400,  // 1 lane, 1.62 Ghz
587    9000,  // 1 lane, 2.70 Ghz
588    10800, // 2 lane, 1.62 Ghz
589    18000, // 2 lane, 2.70 Ghz
590    21600, // 4 lane, 1.62 Ghz
591    36000, // 4 lane, 2.70 Ghz
592};
593static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
594
595# define DP_LINK_BW_1_62                    0x06
596# define DP_LINK_BW_2_7                     0x0a
597static int radeon_dp_max_lane_count(xf86OutputPtr output);
598
599static int
600dp_lanes_for_mode_clock(xf86OutputPtr output, int mode_clock)
601{
602    RADEONOutputPrivatePtr radeon_output = output->driver_private;
603    int i;
604    int max_link_bw = radeon_output->dpcd[1];
605    int max_lane_count = radeon_dp_max_lane_count(output);
606
607    switch (max_link_bw) {
608    case DP_LINK_BW_1_62:
609    default:
610	for (i = 0; i < num_dp_clocks; i++) {
611		if (i % 2)
612			continue;
613		switch (max_lane_count) {
614		case 1:
615			if (i > 1)
616				return 0;
617			break;
618		case 2:
619			if (i > 3)
620				return 0;
621			break;
622		case 4:
623		default:
624			break;
625		}
626		if (dp_clocks[i] > (mode_clock/10)) {
627			if (i < 2)
628				return 1;
629			else if (i < 4)
630				return 2;
631			else
632				return 4;
633		}
634	}
635	break;
636    case DP_LINK_BW_2_7:
637	for (i = 0; i < num_dp_clocks; i++) {
638		switch (max_lane_count) {
639		case 1:
640			if (i > 1)
641				return 0;
642			break;
643		case 2:
644			if (i > 3)
645				return 0;
646			break;
647		case 4:
648		default:
649			break;
650		}
651		if (dp_clocks[i] > (mode_clock/10)) {
652			if (i < 2)
653				return 1;
654			else if (i < 4)
655				return 2;
656			else
657				return 4;
658		}
659	}
660        break;
661    }
662
663    return 0;
664}
665
666static int
667dp_link_clock_for_mode_clock(xf86OutputPtr output, int mode_clock)
668{
669    RADEONOutputPrivatePtr radeon_output = output->driver_private;
670    int i;
671    int max_link_bw = radeon_output->dpcd[1];
672    int max_lane_count = radeon_dp_max_lane_count(output);
673
674    switch (max_link_bw) {
675    case DP_LINK_BW_1_62:
676    default:
677	for (i = 0; i < num_dp_clocks; i++) {
678		if (i % 2)
679			continue;
680		switch (max_lane_count) {
681		case 1:
682			if (i > 1)
683				return 0;
684			break;
685		case 2:
686			if (i > 3)
687				return 0;
688			break;
689		case 4:
690		default:
691			break;
692		}
693		if (dp_clocks[i] > (mode_clock/10))
694			return 16200;
695	}
696	break;
697    case DP_LINK_BW_2_7:
698	for (i = 0; i < num_dp_clocks; i++) {
699		switch (max_lane_count) {
700		case 1:
701			if (i > 1)
702				return 0;
703			break;
704		case 2:
705			if (i > 3)
706				return 0;
707			break;
708		case 4:
709		default:
710			break;
711		}
712		if (dp_clocks[i] > (mode_clock/10))
713			return (i % 2) ? 27000 : 16200;
714	}
715        break;
716    }
717
718    return 0;
719}
720
721/*
722 * DIG Encoder/Transmitter Setup
723 *
724 * DCE 3.0/3.1
725 * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
726 * Supports up to 3 digital outputs
727 * - 2 DIG encoder blocks.
728 * DIG1 can drive UNIPHY link A or link B
729 * DIG2 can drive UNIPHY link B or LVTMA
730 *
731 * DCE 3.2
732 * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
733 * Supports up to 5 digital outputs
734 * - 2 DIG encoder blocks.
735 * DIG1/2 can drive UNIPHY0/1/2 link A or link B
736 *
737 * DCE 4.0
738 * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B).
739 * Supports up to 6 digital outputs
740 * - 6 DIG encoder blocks.
741 * - DIG to PHY mapping is hardcoded
742 * DIG1 drives UNIPHY0 link A, A+B
743 * DIG2 drives UNIPHY0 link B
744 * DIG3 drives UNIPHY1 link A, A+B
745 * DIG4 drives UNIPHY1 link B
746 * DIG5 drives UNIPHY2 link A, A+B
747 * DIG6 drives UNIPHY2 link B
748 *
749 * Routing
750 * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
751 * Examples:
752 * crtc0 -> dig2 -> LVTMA links A+B
753 * crtc1 -> dig1 -> UNIPHY0 link B
754 * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
755 * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
756 */
757
758union dig_encoder_control {
759	DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
760	DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
761	DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
762};
763
764static int
765atombios_output_dig_encoder_setup(xf86OutputPtr output, int action)
766{
767    RADEONOutputPrivatePtr radeon_output = output->driver_private;
768    RADEONInfoPtr info       = RADEONPTR(output->scrn);
769    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
770    union dig_encoder_control disp_data;
771    AtomBiosArgRec data;
772    unsigned char *space;
773    int index = 0, major, minor;
774    int clock = radeon_output->pixel_clock;
775
776    if (radeon_encoder == NULL)
777	return ATOM_NOT_IMPLEMENTED;
778
779    memset(&disp_data,0, sizeof(disp_data));
780
781    if (IS_DCE4_VARIANT)
782	index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
783    else if (radeon_output->dig_encoder)
784        index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
785    else
786        index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
787
788    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
789
790    disp_data.v1.ucAction = action;
791    disp_data.v1.usPixelClock = cpu_to_le16(clock / 10);
792    disp_data.v1.ucEncoderMode = atombios_get_encoder_mode(output);
793
794    if (disp_data.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
795	if (dp_link_clock_for_mode_clock(output, clock) == 27000)
796	    disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
797	disp_data.v1.ucLaneNum = dp_lanes_for_mode_clock(output, clock);
798    } else if (clock > 165000)
799	disp_data.v1.ucLaneNum = 8;
800    else
801	disp_data.v1.ucLaneNum = 4;
802
803    if (IS_DCE4_VARIANT) {
804	disp_data.v3.acConfig.ucDigSel = radeon_output->dig_encoder;
805	disp_data.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
806    } else {
807	switch (radeon_encoder->encoder_id) {
808	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
809	    disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
810	    break;
811	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
812	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
813	    disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
814	    break;
815	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
816	    disp_data.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
817	    break;
818	}
819	if (radeon_output->linkb)
820	    disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
821	else
822	    disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
823    }
824
825    data.exec.index = index;
826    data.exec.dataSpace = (void *)&space;
827    data.exec.pspace = &disp_data;
828
829    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
830	ErrorF("Output DIG%d encoder setup success\n", radeon_output->dig_encoder);
831	return ATOM_SUCCESS;
832    }
833
834    ErrorF("Output DIG%d setup failed\n", radeon_output->dig_encoder);
835    return ATOM_NOT_IMPLEMENTED;
836
837}
838
839union dig_transmitter_control {
840    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
841    DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
842    DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
843};
844
845static int
846atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t lane_num, uint8_t lane_set)
847{
848    RADEONOutputPrivatePtr radeon_output = output->driver_private;
849    RADEONInfoPtr info       = RADEONPTR(output->scrn);
850    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
851    union dig_transmitter_control disp_data;
852    AtomBiosArgRec data;
853    unsigned char *space;
854    int index = 0, num = 0;
855    int major, minor;
856    int clock = radeon_output->pixel_clock;
857
858    if (radeon_encoder == NULL)
859        return ATOM_NOT_IMPLEMENTED;
860
861    memset(&disp_data,0, sizeof(disp_data));
862
863    if (IS_DCE32_VARIANT || IS_DCE4_VARIANT)
864	index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
865    else {
866	switch (radeon_encoder->encoder_id) {
867	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
868	    index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
869	    break;
870	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
871	    index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
872	    break;
873	}
874    }
875
876    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
877
878    disp_data.v1.ucAction = action;
879    if (action == ATOM_TRANSMITTER_ACTION_INIT) {
880        disp_data.v1.usInitInfo = radeon_output->connector_object_id;
881    } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
882	disp_data.v1.asMode.ucLaneSel = lane_num;
883	disp_data.v1.asMode.ucLaneSet = lane_set;
884    } else {
885	if (radeon_output->MonType == MT_DP)
886	    disp_data.v1.usPixelClock =
887		cpu_to_le16(dp_link_clock_for_mode_clock(output, clock));
888	else if (clock > 165000)
889	    disp_data.v1.usPixelClock = cpu_to_le16((clock / 2) / 10);
890	else
891	    disp_data.v1.usPixelClock = cpu_to_le16(clock / 10);
892    }
893
894    if (IS_DCE4_VARIANT) {
895	if (radeon_output->MonType == MT_DP)
896	    disp_data.v3.ucLaneNum = dp_lanes_for_mode_clock(output, clock);
897	else if (clock > 165000)
898	    disp_data.v3.ucLaneNum = 8;
899	else
900	    disp_data.v3.ucLaneNum = 4;
901
902	if (radeon_output->linkb) {
903	    disp_data.v3.acConfig.ucLinkSel = 1;
904	    disp_data.v2.acConfig.ucEncoderSel = 1;
905	}
906
907	// select the PLL for the UNIPHY
908	if (radeon_output->MonType == MT_DP && info->dp_extclk)
909	    disp_data.v3.acConfig.ucRefClkSource = 2; /* ext clk */
910	else
911	    disp_data.v3.acConfig.ucRefClkSource = radeon_output->pll_id;
912
913	switch (radeon_encoder->encoder_id) {
914	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
915	    disp_data.v3.acConfig.ucTransmitterSel = 0;
916	    num = 0;
917	    break;
918	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
919	    disp_data.v3.acConfig.ucTransmitterSel = 1;
920	    num = 1;
921	    break;
922	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
923	    disp_data.v3.acConfig.ucTransmitterSel = 2;
924	    num = 2;
925	    break;
926	}
927
928	if (radeon_output->MonType == MT_DP)
929	    disp_data.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */
930	else if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
931	    if (radeon_output->coherent_mode)
932		disp_data.v3.acConfig.fCoherentMode = 1;
933	    if (clock > 165000)
934		disp_data.v3.acConfig.fDualLinkConnector = 1;
935	}
936    } else if (IS_DCE32_VARIANT) {
937	if (radeon_output->dig_encoder)
938	    disp_data.v2.acConfig.ucEncoderSel = 1;
939
940	if (radeon_output->linkb)
941	    disp_data.v2.acConfig.ucLinkSel = 1;
942
943	switch (radeon_encoder->encoder_id) {
944	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
945	    disp_data.v2.acConfig.ucTransmitterSel = 0;
946	    num = 0;
947	    break;
948	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
949	    disp_data.v2.acConfig.ucTransmitterSel = 1;
950	    num = 1;
951	    break;
952	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
953	    disp_data.v2.acConfig.ucTransmitterSel = 2;
954	    num = 2;
955	    break;
956	}
957
958	if (radeon_output->MonType == MT_DP)
959	    disp_data.v2.acConfig.fCoherentMode = 1; /* DP requires coherent */
960	else if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
961	    if (radeon_output->coherent_mode)
962		disp_data.v2.acConfig.fCoherentMode = 1;
963	    if (clock > 165000)
964		disp_data.v2.acConfig.fDualLinkConnector = 1;
965	}
966    } else {
967	disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
968
969	if (radeon_output->dig_encoder)
970	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
971	else
972	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
973
974	switch (radeon_encoder->encoder_id) {
975	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
976	    if (info->IsIGP) {
977		if (clock > 165000) {
978		    if (radeon_output->igp_lane_info & 0x3)
979			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
980		    else if (radeon_output->igp_lane_info & 0xc)
981			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
982		} else {
983		    if (radeon_output->igp_lane_info & 0x1)
984			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
985		    else if (radeon_output->igp_lane_info & 0x2)
986			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
987		    else if (radeon_output->igp_lane_info & 0x4)
988			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
989		    else if (radeon_output->igp_lane_info & 0x8)
990			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
991		}
992	    }
993	    break;
994	}
995	if (radeon_output->linkb)
996	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
997	else
998	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
999
1000	if (radeon_output->MonType == MT_DP)
1001	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;  /* DP requires coherent */
1002	else if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
1003	    if (radeon_output->coherent_mode)
1004		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
1005	    if (clock > 165000)
1006		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
1007	}
1008    }
1009
1010    data.exec.index = index;
1011    data.exec.dataSpace = (void *)&space;
1012    data.exec.pspace = &disp_data;
1013
1014    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
1015	if (IS_DCE32_VARIANT)
1016	    ErrorF("Output UNIPHY%d transmitter setup success\n", num);
1017	else
1018	   ErrorF("Output DIG%d transmitter setup success\n", num);
1019	return ATOM_SUCCESS;
1020    }
1021
1022    ErrorF("Output DIG%d transmitter setup failed\n", num);
1023    return ATOM_NOT_IMPLEMENTED;
1024
1025}
1026
1027static void atom_rv515_force_tv_scaler(ScrnInfoPtr pScrn, RADEONCrtcPrivatePtr radeon_crtc)
1028{
1029    RADEONInfoPtr info       = RADEONPTR(pScrn);
1030    unsigned char *RADEONMMIO = info->MMIO;
1031    int index_reg = 0x6578, data_reg = 0x657c;
1032
1033    index_reg += radeon_crtc->crtc_offset;
1034    data_reg += radeon_crtc->crtc_offset;
1035
1036    OUTREG(0x659C + radeon_crtc->crtc_offset, 0x0);
1037    OUTREG(0x6594 + radeon_crtc->crtc_offset, 0x705);
1038    OUTREG(0x65A4 + radeon_crtc->crtc_offset, 0x10001);
1039    OUTREG(0x65D8 + radeon_crtc->crtc_offset, 0x0);
1040    OUTREG(0x65B0 + radeon_crtc->crtc_offset, 0x0);
1041    OUTREG(0x65C0 + radeon_crtc->crtc_offset, 0x0);
1042    OUTREG(0x65D4 + radeon_crtc->crtc_offset, 0x0);
1043    OUTREG(index_reg,0x0);
1044    OUTREG(data_reg,0x841880A8);
1045    OUTREG(index_reg,0x1);
1046    OUTREG(data_reg,0x84208680);
1047    OUTREG(index_reg,0x2);
1048    OUTREG(data_reg,0xBFF880B0);
1049    OUTREG(index_reg,0x100);
1050    OUTREG(data_reg,0x83D88088);
1051    OUTREG(index_reg,0x101);
1052    OUTREG(data_reg,0x84608680);
1053    OUTREG(index_reg,0x102);
1054    OUTREG(data_reg,0xBFF080D0);
1055    OUTREG(index_reg,0x200);
1056    OUTREG(data_reg,0x83988068);
1057    OUTREG(index_reg,0x201);
1058    OUTREG(data_reg,0x84A08680);
1059    OUTREG(index_reg,0x202);
1060    OUTREG(data_reg,0xBFF080F8);
1061    OUTREG(index_reg,0x300);
1062    OUTREG(data_reg,0x83588058);
1063    OUTREG(index_reg,0x301);
1064    OUTREG(data_reg,0x84E08660);
1065    OUTREG(index_reg,0x302);
1066    OUTREG(data_reg,0xBFF88120);
1067    OUTREG(index_reg,0x400);
1068    OUTREG(data_reg,0x83188040);
1069    OUTREG(index_reg,0x401);
1070    OUTREG(data_reg,0x85008660);
1071    OUTREG(index_reg,0x402);
1072    OUTREG(data_reg,0xBFF88150);
1073    OUTREG(index_reg,0x500);
1074    OUTREG(data_reg,0x82D88030);
1075    OUTREG(index_reg,0x501);
1076    OUTREG(data_reg,0x85408640);
1077    OUTREG(index_reg,0x502);
1078    OUTREG(data_reg,0xBFF88180);
1079    OUTREG(index_reg,0x600);
1080    OUTREG(data_reg,0x82A08018);
1081    OUTREG(index_reg,0x601);
1082    OUTREG(data_reg,0x85808620);
1083    OUTREG(index_reg,0x602);
1084    OUTREG(data_reg,0xBFF081B8);
1085    OUTREG(index_reg,0x700);
1086    OUTREG(data_reg,0x82608010);
1087    OUTREG(index_reg,0x701);
1088    OUTREG(data_reg,0x85A08600);
1089    OUTREG(index_reg,0x702);
1090    OUTREG(data_reg,0x800081F0);
1091    OUTREG(index_reg,0x800);
1092    OUTREG(data_reg,0x8228BFF8);
1093    OUTREG(index_reg,0x801);
1094    OUTREG(data_reg,0x85E085E0);
1095    OUTREG(index_reg,0x802);
1096    OUTREG(data_reg,0xBFF88228);
1097    OUTREG(index_reg,0x10000);
1098    OUTREG(data_reg,0x82A8BF00);
1099    OUTREG(index_reg,0x10001);
1100    OUTREG(data_reg,0x82A08CC0);
1101    OUTREG(index_reg,0x10002);
1102    OUTREG(data_reg,0x8008BEF8);
1103    OUTREG(index_reg,0x10100);
1104    OUTREG(data_reg,0x81F0BF28);
1105    OUTREG(index_reg,0x10101);
1106    OUTREG(data_reg,0x83608CA0);
1107    OUTREG(index_reg,0x10102);
1108    OUTREG(data_reg,0x8018BED0);
1109    OUTREG(index_reg,0x10200);
1110    OUTREG(data_reg,0x8148BF38);
1111    OUTREG(index_reg,0x10201);
1112    OUTREG(data_reg,0x84408C80);
1113    OUTREG(index_reg,0x10202);
1114    OUTREG(data_reg,0x8008BEB8);
1115    OUTREG(index_reg,0x10300);
1116    OUTREG(data_reg,0x80B0BF78);
1117    OUTREG(index_reg,0x10301);
1118    OUTREG(data_reg,0x85008C20);
1119    OUTREG(index_reg,0x10302);
1120    OUTREG(data_reg,0x8020BEA0);
1121    OUTREG(index_reg,0x10400);
1122    OUTREG(data_reg,0x8028BF90);
1123    OUTREG(index_reg,0x10401);
1124    OUTREG(data_reg,0x85E08BC0);
1125    OUTREG(index_reg,0x10402);
1126    OUTREG(data_reg,0x8018BE90);
1127    OUTREG(index_reg,0x10500);
1128    OUTREG(data_reg,0xBFB8BFB0);
1129    OUTREG(index_reg,0x10501);
1130    OUTREG(data_reg,0x86C08B40);
1131    OUTREG(index_reg,0x10502);
1132    OUTREG(data_reg,0x8010BE90);
1133    OUTREG(index_reg,0x10600);
1134    OUTREG(data_reg,0xBF58BFC8);
1135    OUTREG(index_reg,0x10601);
1136    OUTREG(data_reg,0x87A08AA0);
1137    OUTREG(index_reg,0x10602);
1138    OUTREG(data_reg,0x8010BE98);
1139    OUTREG(index_reg,0x10700);
1140    OUTREG(data_reg,0xBF10BFF0);
1141    OUTREG(index_reg,0x10701);
1142    OUTREG(data_reg,0x886089E0);
1143    OUTREG(index_reg,0x10702);
1144    OUTREG(data_reg,0x8018BEB0);
1145    OUTREG(index_reg,0x10800);
1146    OUTREG(data_reg,0xBED8BFE8);
1147    OUTREG(index_reg,0x10801);
1148    OUTREG(data_reg,0x89408940);
1149    OUTREG(index_reg,0x10802);
1150    OUTREG(data_reg,0xBFE8BED8);
1151    OUTREG(index_reg,0x20000);
1152    OUTREG(data_reg,0x80008000);
1153    OUTREG(index_reg,0x20001);
1154    OUTREG(data_reg,0x90008000);
1155    OUTREG(index_reg,0x20002);
1156    OUTREG(data_reg,0x80008000);
1157    OUTREG(index_reg,0x20003);
1158    OUTREG(data_reg,0x80008000);
1159    OUTREG(index_reg,0x20100);
1160    OUTREG(data_reg,0x80108000);
1161    OUTREG(index_reg,0x20101);
1162    OUTREG(data_reg,0x8FE0BF70);
1163    OUTREG(index_reg,0x20102);
1164    OUTREG(data_reg,0xBFE880C0);
1165    OUTREG(index_reg,0x20103);
1166    OUTREG(data_reg,0x80008000);
1167    OUTREG(index_reg,0x20200);
1168    OUTREG(data_reg,0x8018BFF8);
1169    OUTREG(index_reg,0x20201);
1170    OUTREG(data_reg,0x8F80BF08);
1171    OUTREG(index_reg,0x20202);
1172    OUTREG(data_reg,0xBFD081A0);
1173    OUTREG(index_reg,0x20203);
1174    OUTREG(data_reg,0xBFF88000);
1175    OUTREG(index_reg,0x20300);
1176    OUTREG(data_reg,0x80188000);
1177    OUTREG(index_reg,0x20301);
1178    OUTREG(data_reg,0x8EE0BEC0);
1179    OUTREG(index_reg,0x20302);
1180    OUTREG(data_reg,0xBFB082A0);
1181    OUTREG(index_reg,0x20303);
1182    OUTREG(data_reg,0x80008000);
1183    OUTREG(index_reg,0x20400);
1184    OUTREG(data_reg,0x80188000);
1185    OUTREG(index_reg,0x20401);
1186    OUTREG(data_reg,0x8E00BEA0);
1187    OUTREG(index_reg,0x20402);
1188    OUTREG(data_reg,0xBF8883C0);
1189    OUTREG(index_reg,0x20403);
1190    OUTREG(data_reg,0x80008000);
1191    OUTREG(index_reg,0x20500);
1192    OUTREG(data_reg,0x80188000);
1193    OUTREG(index_reg,0x20501);
1194    OUTREG(data_reg,0x8D00BE90);
1195    OUTREG(index_reg,0x20502);
1196    OUTREG(data_reg,0xBF588500);
1197    OUTREG(index_reg,0x20503);
1198    OUTREG(data_reg,0x80008008);
1199    OUTREG(index_reg,0x20600);
1200    OUTREG(data_reg,0x80188000);
1201    OUTREG(index_reg,0x20601);
1202    OUTREG(data_reg,0x8BC0BE98);
1203    OUTREG(index_reg,0x20602);
1204    OUTREG(data_reg,0xBF308660);
1205    OUTREG(index_reg,0x20603);
1206    OUTREG(data_reg,0x80008008);
1207    OUTREG(index_reg,0x20700);
1208    OUTREG(data_reg,0x80108000);
1209    OUTREG(index_reg,0x20701);
1210    OUTREG(data_reg,0x8A80BEB0);
1211    OUTREG(index_reg,0x20702);
1212    OUTREG(data_reg,0xBF0087C0);
1213    OUTREG(index_reg,0x20703);
1214    OUTREG(data_reg,0x80008008);
1215    OUTREG(index_reg,0x20800);
1216    OUTREG(data_reg,0x80108000);
1217    OUTREG(index_reg,0x20801);
1218    OUTREG(data_reg,0x8920BED0);
1219    OUTREG(index_reg,0x20802);
1220    OUTREG(data_reg,0xBED08920);
1221    OUTREG(index_reg,0x20803);
1222    OUTREG(data_reg,0x80008010);
1223    OUTREG(index_reg,0x30000);
1224    OUTREG(data_reg,0x90008000);
1225    OUTREG(index_reg,0x30001);
1226    OUTREG(data_reg,0x80008000);
1227    OUTREG(index_reg,0x30100);
1228    OUTREG(data_reg,0x8FE0BF90);
1229    OUTREG(index_reg,0x30101);
1230    OUTREG(data_reg,0xBFF880A0);
1231    OUTREG(index_reg,0x30200);
1232    OUTREG(data_reg,0x8F60BF40);
1233    OUTREG(index_reg,0x30201);
1234    OUTREG(data_reg,0xBFE88180);
1235    OUTREG(index_reg,0x30300);
1236    OUTREG(data_reg,0x8EC0BF00);
1237    OUTREG(index_reg,0x30301);
1238    OUTREG(data_reg,0xBFC88280);
1239    OUTREG(index_reg,0x30400);
1240    OUTREG(data_reg,0x8DE0BEE0);
1241    OUTREG(index_reg,0x30401);
1242    OUTREG(data_reg,0xBFA083A0);
1243    OUTREG(index_reg,0x30500);
1244    OUTREG(data_reg,0x8CE0BED0);
1245    OUTREG(index_reg,0x30501);
1246    OUTREG(data_reg,0xBF7884E0);
1247    OUTREG(index_reg,0x30600);
1248    OUTREG(data_reg,0x8BA0BED8);
1249    OUTREG(index_reg,0x30601);
1250    OUTREG(data_reg,0xBF508640);
1251    OUTREG(index_reg,0x30700);
1252    OUTREG(data_reg,0x8A60BEE8);
1253    OUTREG(index_reg,0x30701);
1254    OUTREG(data_reg,0xBF2087A0);
1255    OUTREG(index_reg,0x30800);
1256    OUTREG(data_reg,0x8900BF00);
1257    OUTREG(index_reg,0x30801);
1258    OUTREG(data_reg,0xBF008900);
1259}
1260
1261static int
1262atombios_output_yuv_setup(xf86OutputPtr output, Bool enable)
1263{
1264    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1265    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1266    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1267    ENABLE_YUV_PS_ALLOCATION disp_data;
1268    AtomBiosArgRec data;
1269    unsigned char *space;
1270    unsigned char *RADEONMMIO = info->MMIO;
1271    uint32_t temp, reg;
1272
1273    if (info->ChipFamily >= CHIP_FAMILY_R600)
1274	reg = R600_BIOS_3_SCRATCH;
1275    else
1276	reg = RADEON_BIOS_3_SCRATCH;
1277
1278    //fix up scratch reg handling
1279    temp = INREG(reg);
1280    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1281	OUTREG(reg, (ATOM_S3_TV1_ACTIVE |
1282		     (radeon_crtc->crtc_id << 18)));
1283    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1284	OUTREG(reg, (ATOM_S3_CV_ACTIVE |
1285		     (radeon_crtc->crtc_id << 24)));
1286    else
1287	OUTREG(reg, 0);
1288
1289    memset(&disp_data, 0, sizeof(disp_data));
1290
1291    if (enable)
1292	disp_data.ucEnable = ATOM_ENABLE;
1293    disp_data.ucCRTC = radeon_crtc->crtc_id;
1294
1295    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
1296    data.exec.dataSpace = (void *)&space;
1297    data.exec.pspace = &disp_data;
1298
1299    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
1300
1301	OUTREG(reg, temp);
1302
1303	ErrorF("crtc %d YUV %s setup success\n", radeon_crtc->crtc_id, enable ? "enable" : "disable");
1304	return ATOM_SUCCESS;
1305    }
1306
1307    OUTREG(reg, temp);
1308
1309    ErrorF("crtc %d YUV %s setup failed\n", radeon_crtc->crtc_id, enable ? "enable" : "disable");
1310    return ATOM_NOT_IMPLEMENTED;
1311
1312}
1313
1314static int
1315atombios_output_overscan_setup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
1316{
1317    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1318    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1319    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1320    SET_CRTC_OVERSCAN_PS_ALLOCATION overscan_param;
1321    AtomBiosArgRec data;
1322    unsigned char *space;
1323    memset(&overscan_param, 0, sizeof(overscan_param));
1324
1325    overscan_param.usOverscanRight = 0;
1326    overscan_param.usOverscanLeft = 0;
1327    overscan_param.usOverscanBottom = 0;
1328    overscan_param.usOverscanTop = 0;
1329    overscan_param.ucCRTC = radeon_crtc->crtc_id;
1330
1331    if (radeon_output->Flags & RADEON_USE_RMX) {
1332	if (radeon_output->rmx_type == RMX_FULL) {
1333	    overscan_param.usOverscanRight = 0;
1334	    overscan_param.usOverscanLeft = 0;
1335	    overscan_param.usOverscanBottom = 0;
1336	    overscan_param.usOverscanTop = 0;
1337	} else if (radeon_output->rmx_type == RMX_CENTER) {
1338	    overscan_param.usOverscanTop = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2;
1339	    overscan_param.usOverscanBottom = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2;
1340	    overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2;
1341	    overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2;
1342	} else if (radeon_output->rmx_type == RMX_ASPECT) {
1343	    int a1 = mode->CrtcVDisplay * adjusted_mode->CrtcHDisplay;
1344	    int a2 = adjusted_mode->CrtcVDisplay * mode->CrtcHDisplay;
1345
1346	    if (a1 > a2) {
1347		overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2;
1348		overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2;
1349	    } else if (a2 > a1) {
1350		overscan_param.usOverscanLeft = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2;
1351		overscan_param.usOverscanRight = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2;
1352	    }
1353	}
1354    }
1355
1356    data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan);
1357    data.exec.dataSpace = (void *)&space;
1358    data.exec.pspace = &overscan_param;
1359
1360    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
1361	ErrorF("Set CRTC %d Overscan success\n", radeon_crtc->crtc_id);
1362	return ATOM_SUCCESS ;
1363    }
1364
1365    ErrorF("Set CRTC %d Overscan failed\n", radeon_crtc->crtc_id);
1366    return ATOM_NOT_IMPLEMENTED;
1367}
1368
1369static int
1370atombios_output_scaler_setup(xf86OutputPtr output)
1371{
1372    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1373    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1374    radeon_tvout_ptr tvout = &radeon_output->tvout;
1375    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1376    ENABLE_SCALER_PS_ALLOCATION disp_data;
1377    AtomBiosArgRec data;
1378    unsigned char *space;
1379
1380    if (!IS_AVIVO_VARIANT && radeon_crtc->crtc_id)
1381	return ATOM_SUCCESS;
1382
1383    memset(&disp_data, 0, sizeof(disp_data));
1384
1385    disp_data.ucScaler = radeon_crtc->crtc_id;
1386
1387    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
1388	switch (tvout->tvStd) {
1389	case TV_STD_NTSC:
1390	    disp_data.ucTVStandard = ATOM_TV_NTSC;
1391	    break;
1392	case TV_STD_PAL:
1393	    disp_data.ucTVStandard = ATOM_TV_PAL;
1394	    break;
1395	case TV_STD_PAL_M:
1396	    disp_data.ucTVStandard = ATOM_TV_PALM;
1397	    break;
1398	case TV_STD_PAL_60:
1399	    disp_data.ucTVStandard = ATOM_TV_PAL60;
1400	    break;
1401	case TV_STD_NTSC_J:
1402	    disp_data.ucTVStandard = ATOM_TV_NTSCJ;
1403	    break;
1404	case TV_STD_SCART_PAL:
1405	    disp_data.ucTVStandard = ATOM_TV_PAL; /* ??? */
1406	    break;
1407	case TV_STD_SECAM:
1408	    disp_data.ucTVStandard = ATOM_TV_SECAM;
1409	    break;
1410	case TV_STD_PAL_CN:
1411	    disp_data.ucTVStandard = ATOM_TV_PALCN;
1412	    break;
1413	default:
1414	    disp_data.ucTVStandard = ATOM_TV_NTSC;
1415	    break;
1416	}
1417	disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
1418        ErrorF("Using TV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable);
1419    } else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
1420	disp_data.ucTVStandard = ATOM_TV_CV;
1421	disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
1422        ErrorF("Using CV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable);
1423    } else if (radeon_output->Flags & RADEON_USE_RMX) {
1424	ErrorF("Using RMX\n");
1425	if (radeon_output->rmx_type == RMX_FULL)
1426	    disp_data.ucEnable = ATOM_SCALER_EXPANSION;
1427	else if (radeon_output->rmx_type == RMX_CENTER)
1428	    disp_data.ucEnable = ATOM_SCALER_CENTER;
1429	else if (radeon_output->rmx_type == RMX_ASPECT)
1430	    disp_data.ucEnable = ATOM_SCALER_EXPANSION;
1431    } else {
1432	ErrorF("Not using RMX\n");
1433	if (IS_AVIVO_VARIANT)
1434	    disp_data.ucEnable = ATOM_SCALER_DISABLE;
1435	else
1436	    disp_data.ucEnable = ATOM_SCALER_CENTER;
1437    }
1438
1439    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
1440    data.exec.dataSpace = (void *)&space;
1441    data.exec.pspace = &disp_data;
1442
1443    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
1444	if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)
1445	    && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) {
1446	    ErrorF("forcing TV scaler\n");
1447	    atom_rv515_force_tv_scaler(output->scrn, radeon_crtc);
1448	}
1449	ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id);
1450	return ATOM_SUCCESS;
1451    }
1452
1453    ErrorF("scaler %d setup failed\n", radeon_crtc->crtc_id);
1454    return ATOM_NOT_IMPLEMENTED;
1455
1456}
1457
1458void
1459atombios_output_dpms(xf86OutputPtr output, int mode)
1460{
1461    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1462    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
1463    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1464    DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data;
1465    AtomBiosArgRec data;
1466    unsigned char *space;
1467    int index = 0;
1468    Bool is_dig = FALSE;
1469
1470    if (radeon_encoder == NULL)
1471        return;
1472    atombios_pick_dig_encoder(output);
1473
1474    switch (radeon_encoder->encoder_id) {
1475    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1476    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1477	index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
1478	break;
1479    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1480    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1481    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1482    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1483	is_dig = TRUE;
1484	break;
1485    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1486    case ENCODER_OBJECT_ID_INTERNAL_DDI:
1487    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1488	index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
1489	break;
1490    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1491	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
1492	break;
1493    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1494	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
1495	    index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
1496	else
1497	    index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
1498	break;
1499    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1500    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1501	if (IS_DCE32_VARIANT)
1502	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
1503	else {
1504	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1505		index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
1506	    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1507		index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
1508	    else
1509		index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
1510	}
1511	break;
1512    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1513    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1514	if (IS_DCE32_VARIANT)
1515	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
1516	else {
1517	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1518		index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
1519	    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1520		index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
1521	    else
1522		index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
1523	}
1524	break;
1525    }
1526
1527    switch (mode) {
1528    case DPMSModeOn:
1529	radeon_encoder->devices |= radeon_output->active_device;
1530	if (is_dig) {
1531	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
1532	    if (((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) ||
1533		 (radeon_output->ConnectorType == CONNECTOR_EDP)) &&
1534		(radeon_output->MonType == MT_DP)) {
1535		do_displayport_link_train(output);
1536		if (IS_DCE4_VARIANT)
1537		    atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_ON);
1538	    }
1539	}
1540	else {
1541	    disp_data.ucAction = ATOM_ENABLE;
1542	    data.exec.index = index;
1543	    data.exec.dataSpace = (void *)&space;
1544	    data.exec.pspace = &disp_data;
1545
1546	    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS)
1547		ErrorF("Output %s enable success\n",
1548		       device_name[radeon_get_device_index(radeon_output->active_device)]);
1549	    else
1550		ErrorF("Output %s enable failed\n",
1551		       device_name[radeon_get_device_index(radeon_output->active_device)]);
1552	}
1553	/* at least for TV atom fails to reassociate the correct crtc source at dpms on */
1554	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1555		atombios_set_output_crtc_source(output);
1556	break;
1557    case DPMSModeStandby:
1558    case DPMSModeSuspend:
1559    case DPMSModeOff:
1560	radeon_encoder->devices &= ~(radeon_output->active_device);
1561	if (!radeon_encoder->devices) {
1562	    if (is_dig) {
1563		atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
1564		if (((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) ||
1565		     (radeon_output->ConnectorType == CONNECTOR_EDP)) &&
1566		    (radeon_output->MonType == MT_DP)) {
1567		    if (IS_DCE4_VARIANT)
1568			atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
1569		}
1570	    } else {
1571		disp_data.ucAction = ATOM_DISABLE;
1572		data.exec.index = index;
1573		data.exec.dataSpace = (void *)&space;
1574		data.exec.pspace = &disp_data;
1575
1576		if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data)
1577		    == ATOM_SUCCESS)
1578		    ErrorF("Output %s disable success\n",
1579			   device_name[radeon_get_device_index(radeon_output->active_device)]);
1580		else
1581		    ErrorF("Output %s disable failed\n",
1582			   device_name[radeon_get_device_index(radeon_output->active_device)]);
1583	    }
1584	}
1585	break;
1586    }
1587}
1588
1589union crtc_source_param {
1590    SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
1591    SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
1592};
1593
1594void
1595atombios_set_output_crtc_source(xf86OutputPtr output)
1596{
1597    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1598    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1599    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1600    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
1601    AtomBiosArgRec data;
1602    unsigned char *space;
1603    union crtc_source_param args;
1604    int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
1605    int major, minor;
1606
1607    if (radeon_encoder == NULL)
1608	return;
1609
1610    memset(&args, 0, sizeof(args));
1611
1612    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
1613
1614    /*ErrorF("select crtc source table is %d %d\n", major, minor);*/
1615
1616    switch(major) {
1617    case 1:
1618	switch(minor) {
1619	case 0:
1620	case 1:
1621	default:
1622	    if (IS_AVIVO_VARIANT)
1623		args.v1.ucCRTC = radeon_crtc->crtc_id;
1624	    else {
1625		if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)
1626		    args.v1.ucCRTC = radeon_crtc->crtc_id;
1627		else
1628		    args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
1629	    }
1630	    switch (radeon_encoder->encoder_id) {
1631	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1632	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1633		args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
1634		break;
1635	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1636	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1637		if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT)
1638		    args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
1639		else
1640		    args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
1641		break;
1642	    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1643	    case ENCODER_OBJECT_ID_INTERNAL_DDI:
1644	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1645		args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
1646		break;
1647	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1648	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1649		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1650		    args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
1651		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1652		    args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
1653		else
1654		    args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
1655		break;
1656	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1657	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1658		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1659		    args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
1660		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1661		    args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
1662		else
1663		    args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
1664		break;
1665	    }
1666	    /*ErrorF("device sourced: 0x%x\n", args.v1.ucDevice);*/
1667	    break;
1668	case 2:
1669	    args.v2.ucCRTC = radeon_crtc->crtc_id;
1670	    args.v2.ucEncodeMode = atombios_get_encoder_mode(output);
1671	    switch (radeon_encoder->encoder_id) {
1672	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1673	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1674	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1675	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1676 		switch (radeon_output->dig_encoder) {
1677 		case 0:
1678 		    args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
1679 		    break;
1680 		case 1:
1681 		    args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1682 		    break;
1683 		case 2:
1684 		    args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
1685 		    break;
1686 		case 3:
1687 		    args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
1688 		    break;
1689 		case 4:
1690 		    args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
1691 		    break;
1692 		case 5:
1693 		    args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
1694 		    break;
1695 		}
1696		break;
1697	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1698		args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
1699		break;
1700	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1701		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1702		    args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1703		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1704		    args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1705		else
1706		    args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
1707		break;
1708	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1709		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
1710		    args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1711		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
1712		    args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1713		else
1714		    args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
1715		break;
1716	    }
1717	    /*ErrorF("device sourced: 0x%x\n", args.v2.ucEncoderID);*/
1718	    break;
1719	}
1720	break;
1721    default:
1722	ErrorF("Unknown table version\n");
1723	exit(-1);
1724    }
1725
1726    data.exec.pspace = &args;
1727    data.exec.index = index;
1728    data.exec.dataSpace = (void *)&space;
1729
1730    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
1731	ErrorF("Set CRTC %d Source success\n", radeon_crtc->crtc_id);
1732	return;
1733    }
1734
1735    ErrorF("Set CRTC Source failed\n");
1736    return;
1737}
1738
1739static void
1740atombios_apply_output_quirks(xf86OutputPtr output, DisplayModePtr mode)
1741{
1742    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1743    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1744    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1745    unsigned char *RADEONMMIO = info->MMIO;
1746
1747    /* Funky macbooks */
1748    if ((info->Chipset == PCI_CHIP_RV530_71C5) &&
1749	(PCI_SUB_VENDOR_ID(info->PciInfo) == 0x106b) &&
1750	(PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0080)) {
1751	if (radeon_output->MonType == MT_LCD) {
1752	    if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
1753		uint32_t lvtma_bit_depth_control = INREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
1754
1755		lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;
1756		lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
1757
1758		OUTREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);
1759	    }
1760	}
1761    }
1762
1763    /* set scaler clears this on some chips */
1764    if (!(radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))) {
1765	if (IS_AVIVO_VARIANT && (mode->Flags & V_INTERLACE))
1766	    OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
1767    }
1768
1769    if (IS_DCE32_VARIANT &&
1770	(!IS_DCE4_VARIANT) &&
1771	(radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
1772	radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
1773	if (radeon_encoder == NULL)
1774	    return;
1775	/* XXX: need to sort out why transmitter control table sometimes sets this to a
1776	 * different golden value.
1777	 */
1778	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY2) {
1779	    OUTREG(0x7ec4, 0x00824002);
1780	}
1781    }
1782}
1783
1784static void
1785atombios_pick_dig_encoder(xf86OutputPtr output)
1786{
1787    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(output->scrn);
1788    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1789    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1790    radeon_encoder_ptr radeon_encoder = NULL;
1791    Bool is_lvtma = FALSE;
1792    int i, mode;
1793    uint32_t dig_enc_use_mask = 0;
1794
1795    /* non digital encoders don't need a dig block */
1796    mode = atombios_get_encoder_mode(output);
1797    if (mode == ATOM_ENCODER_MODE_CRT ||
1798        mode == ATOM_ENCODER_MODE_TV ||
1799        mode == ATOM_ENCODER_MODE_CV)
1800        return;
1801
1802    if (IS_DCE4_VARIANT) {
1803        radeon_encoder = radeon_get_encoder(output);
1804
1805	if (IS_DCE41_VARIANT) {
1806	    if (radeon_output->linkb)
1807		radeon_output->dig_encoder = 1;
1808	    else
1809		radeon_output->dig_encoder = 0;
1810	} else {
1811	    switch (radeon_encoder->encoder_id) {
1812	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1813		if (radeon_output->linkb)
1814		    radeon_output->dig_encoder = 1;
1815		else
1816		    radeon_output->dig_encoder = 0;
1817		break;
1818	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1819		if (radeon_output->linkb)
1820		    radeon_output->dig_encoder = 3;
1821		else
1822		    radeon_output->dig_encoder = 2;
1823		break;
1824	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1825		if (radeon_output->linkb)
1826		    radeon_output->dig_encoder = 5;
1827		else
1828		    radeon_output->dig_encoder = 4;
1829		break;
1830	    default:
1831		ErrorF("Unknown encoder\n");
1832		break;
1833	    }
1834	}
1835	return;
1836    }
1837
1838    if (IS_DCE32_VARIANT) {
1839        RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
1840        radeon_output->dig_encoder = radeon_crtc->crtc_id;
1841        return;
1842    }
1843
1844    for (i = 0; i < xf86_config->num_output; i++) {
1845        xf86OutputPtr test = xf86_config->output[i];
1846        RADEONOutputPrivatePtr radeon_test = test->driver_private;
1847        radeon_encoder = radeon_get_encoder(test);
1848
1849        if (!radeon_encoder || !test->crtc)
1850            continue;
1851
1852        if (output == test && radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA)
1853            is_lvtma = TRUE;
1854        if (output != test && (radeon_test->dig_encoder >= 0))
1855            dig_enc_use_mask |= (1 << radeon_test->dig_encoder);
1856
1857    }
1858    if (is_lvtma) {
1859        if (dig_enc_use_mask & 0x2)
1860            ErrorF("Need digital encoder 2 for LVTMA and it isn't free - stealing\n");
1861        radeon_output->dig_encoder = 1;
1862        return;
1863    }
1864    if (!(dig_enc_use_mask & 1))
1865        radeon_output->dig_encoder = 0;
1866    else
1867        radeon_output->dig_encoder = 1;
1868}
1869void
1870atombios_output_mode_set(xf86OutputPtr output,
1871			 DisplayModePtr mode,
1872			 DisplayModePtr adjusted_mode)
1873{
1874    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1875    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
1876    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1877    if (radeon_encoder == NULL)
1878	return;
1879
1880    radeon_output->pixel_clock = adjusted_mode->Clock;
1881    atombios_pick_dig_encoder(output);
1882    atombios_output_overscan_setup(output, mode, adjusted_mode);
1883    atombios_output_scaler_setup(output);
1884    atombios_set_output_crtc_source(output);
1885
1886    if (IS_AVIVO_VARIANT && !IS_DCE4_VARIANT) {
1887	if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
1888	    atombios_output_yuv_setup(output, TRUE);
1889	else
1890	    atombios_output_yuv_setup(output, FALSE);
1891    }
1892
1893    switch (radeon_encoder->encoder_id) {
1894    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1895    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
1896    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
1897    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
1898	atombios_output_digital_setup(output, PANEL_ENCODER_ACTION_ENABLE);
1899	break;
1900    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1901    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1902    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1903    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1904	/* disable encoder and transmitter */
1905	/* setup and enable the encoder and transmitter */
1906	if (IS_DCE4_VARIANT) {
1907	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
1908	    atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_SETUP);
1909	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
1910	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1911	} else {
1912	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
1913	    atombios_output_dig_encoder_setup(output, ATOM_DISABLE);
1914	    atombios_output_dig_encoder_setup(output, ATOM_ENABLE);
1915
1916	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
1917	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
1918	    atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
1919	}
1920	break;
1921    case ENCODER_OBJECT_ID_INTERNAL_DDI:
1922	atombios_output_ddia_setup(output, ATOM_ENABLE);
1923	break;
1924    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
1925    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1926	atombios_external_tmds_setup(output, ATOM_ENABLE);
1927	break;
1928    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1929    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1930    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1931    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1932	atombios_output_dac_setup(output, ATOM_ENABLE);
1933	if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
1934		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1935			atombios_output_tv_setup(output, ATOM_ENABLE);
1936		else
1937			atombios_output_tv_setup(output, ATOM_DISABLE);
1938	}
1939	break;
1940    }
1941    atombios_apply_output_quirks(output, adjusted_mode);
1942}
1943
1944static AtomBiosResult
1945atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
1946{
1947    RADEONOutputPrivatePtr radeon_output = output->driver_private;
1948    RADEONInfoPtr info       = RADEONPTR(output->scrn);
1949    DAC_LOAD_DETECTION_PS_ALLOCATION dac_data;
1950    AtomBiosArgRec data;
1951    unsigned char *space;
1952    int major, minor;
1953    int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
1954
1955    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
1956
1957    dac_data.sDacload.ucMisc = 0;
1958
1959    if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
1960	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
1961	if (info->encoders[ATOM_DEVICE_CRT1_INDEX] &&
1962	    ((info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1963	     (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)))
1964	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
1965	else
1966	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
1967    } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
1968	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
1969	if (info->encoders[ATOM_DEVICE_CRT2_INDEX] &&
1970	    ((info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1971	     (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)))
1972	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
1973	else
1974	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
1975    } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
1976	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
1977	if (info->encoders[ATOM_DEVICE_CV_INDEX] &&
1978	    ((info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1979	     (info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)))
1980	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
1981	else
1982	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
1983	if (minor >= 3)
1984	    dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1985    } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
1986	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
1987	if (info->encoders[ATOM_DEVICE_TV1_INDEX] &&
1988	    ((info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
1989	     (info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)))
1990	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
1991	else
1992	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
1993	if (minor >= 3)
1994	    dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1995    } else
1996	return ATOM_NOT_IMPLEMENTED;
1997
1998    data.exec.index = index;
1999    data.exec.dataSpace = (void *)&space;
2000    data.exec.pspace = &dac_data;
2001
2002    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
2003	ErrorF("Dac detection success\n");
2004	return ATOM_SUCCESS ;
2005    }
2006
2007    ErrorF("DAC detection failed\n");
2008    return ATOM_NOT_IMPLEMENTED;
2009}
2010
2011RADEONMonitorType
2012atombios_dac_detect(xf86OutputPtr output)
2013{
2014    ScrnInfoPtr pScrn = output->scrn;
2015    RADEONInfoPtr info       = RADEONPTR(pScrn);
2016    unsigned char *RADEONMMIO = info->MMIO;
2017    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2018    RADEONMonitorType MonType = MT_NONE;
2019    AtomBiosResult ret;
2020    RADEONSavePtr save = info->ModeReg;
2021
2022    if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
2023	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
2024	    if (radeon_output->ConnectorType == CONNECTOR_STV)
2025		return MT_STV;
2026	    else
2027		return MT_CTV;
2028	}
2029    }
2030
2031    ret = atom_bios_dac_load_detect(info->atomBIOS, output);
2032    if (ret == ATOM_SUCCESS) {
2033	if (info->ChipFamily >= CHIP_FAMILY_R600)
2034	    save->bios_0_scratch = INREG(R600_BIOS_0_SCRATCH);
2035	else
2036	    save->bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH);
2037	/*ErrorF("DAC connect %08X\n", (unsigned int)save->bios_0_scratch);*/
2038
2039	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
2040	    if (save->bios_0_scratch & ATOM_S0_CRT1_MASK)
2041		MonType = MT_CRT;
2042	} else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
2043	    if (save->bios_0_scratch & ATOM_S0_CRT2_MASK)
2044		MonType = MT_CRT;
2045	} else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
2046	    if (save->bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A))
2047		MonType = MT_CV;
2048	} else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
2049	    if (save->bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
2050		MonType = MT_CTV;
2051	    else if (save->bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
2052		MonType = MT_STV;
2053	}
2054    }
2055
2056    return MonType;
2057}
2058
2059
2060static inline int atom_dp_get_encoder_id(xf86OutputPtr output)
2061{
2062    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2063    int ret = 0;
2064    if (radeon_output->dig_encoder)
2065        ret |= ATOM_DP_CONFIG_DIG2_ENCODER;
2066    else
2067        ret |= ATOM_DP_CONFIG_DIG1_ENCODER;
2068    if (radeon_output->linkb)
2069        ret |= ATOM_DP_CONFIG_LINK_B;
2070    else
2071        ret |= ATOM_DP_CONFIG_LINK_A;
2072    return ret;
2073}
2074
2075union aux_channel_transaction {
2076    PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
2077    PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
2078};
2079
2080Bool
2081RADEONProcessAuxCH(xf86OutputPtr output, uint8_t *req_bytes, uint8_t num_bytes,
2082		   uint8_t *read_byte, uint8_t read_buf_len, uint8_t delay)
2083{
2084    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2085    RADEONInfoPtr info       = RADEONPTR(output->scrn);
2086    union aux_channel_transaction args;
2087    AtomBiosArgRec data;
2088    unsigned char *space;
2089    unsigned char *base;
2090    int retry_count = 0;
2091
2092    memset(&args, 0, sizeof(args));
2093    if (info->atomBIOS->fbBase)
2094	base = info->FB + info->atomBIOS->fbBase;
2095    else if (info->atomBIOS->scratchBase)
2096	base = (unsigned char *)info->atomBIOS->scratchBase;
2097    else
2098	return FALSE;
2099
2100retry:
2101    memcpy(base, req_bytes, num_bytes);
2102
2103    args.v1.lpAuxRequest = 0;
2104    args.v1.lpDataOut = 16;
2105    args.v1.ucDataOutLen = 0;
2106    args.v1.ucChannelID = radeon_output->ucI2cId;
2107    args.v1.ucDelay = delay / 10; /* 10 usec */
2108    if (IS_DCE4_VARIANT)
2109	args.v2.ucHPD_ID = radeon_output->hpd_id;
2110
2111    data.exec.index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
2112    data.exec.dataSpace = (void *)&space;
2113    data.exec.pspace = &args;
2114
2115    RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data);
2116    if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
2117	if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
2118		goto retry;
2119	ErrorF("failed to get auxch %02x%02x %02x %02x %02x after %d retries\n",
2120	       req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], args.v1.ucReplyStatus, retry_count);
2121	return FALSE;
2122    }
2123    if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
2124	if (read_buf_len < args.v1.ucDataOutLen) {
2125	    ErrorF("%s: Buffer too small for return answer %d %d\n", __func__, read_buf_len, args.v1.ucDataOutLen);
2126	    return FALSE;
2127	}
2128	{
2129	    int len = read_buf_len < args.v1.ucDataOutLen ? read_buf_len : args.v1.ucDataOutLen;
2130	    memcpy(read_byte, base+16, len);
2131	}
2132    }
2133    return TRUE;
2134}
2135
2136static int
2137RADEONDPEncoderService(xf86OutputPtr output, int action, uint8_t ucconfig, uint8_t lane_num)
2138{
2139    RADEONInfoPtr info = RADEONPTR(output->scrn);
2140    DP_ENCODER_SERVICE_PARAMETERS args;
2141    AtomBiosArgRec data;
2142    unsigned char *space;
2143
2144    memset(&args, 0, sizeof(args));
2145
2146    args.ucLinkClock = 0;
2147    args.ucConfig = ucconfig;
2148    args.ucAction = action;
2149    args.ucLaneNum = lane_num;
2150    args.ucStatus = 0;
2151
2152    data.exec.index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
2153    data.exec.dataSpace = (void *)&space;
2154    data.exec.pspace = &args;
2155
2156    RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data);
2157
2158    ErrorF("%s: %d %d\n", __func__, action, args.ucStatus);
2159    return args.ucStatus;
2160}
2161
2162int RADEON_DP_GetSinkType(xf86OutputPtr output)
2163{
2164    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2165
2166    return RADEONDPEncoderService(output, ATOM_DP_ACTION_GET_SINK_TYPE, radeon_output->ucI2cId, 0);
2167}
2168
2169static Bool atom_dp_aux_native_write(xf86OutputPtr output, uint16_t address,
2170				     uint8_t send_bytes, uint8_t *send)
2171{
2172    uint8_t msg[20];
2173    uint8_t msg_len, dp_msg_len;
2174    int ret;
2175
2176    dp_msg_len = 4;
2177    msg[0] = address;
2178    msg[1] = address >> 8;
2179    msg[2] = AUX_NATIVE_WRITE << 4;
2180    dp_msg_len += send_bytes;
2181    msg[3] = (dp_msg_len << 4)| (send_bytes - 1);
2182
2183    if (0)
2184	ErrorF("writing %02x %02x %02x, %d, %d\n", msg[0], msg[1], msg[3], send_bytes, dp_msg_len);
2185    if (send_bytes > 16)
2186	return FALSE;
2187
2188    memcpy(&msg[4], send, send_bytes);
2189    msg_len = 4 + send_bytes;
2190    ret = RADEONProcessAuxCH(output, msg, msg_len, NULL, 0, 0);
2191    return ret;
2192}
2193
2194static Bool atom_dp_aux_native_read(xf86OutputPtr output, uint16_t address,
2195				    uint8_t delay,
2196				    uint8_t expected_bytes, uint8_t *read_p)
2197{
2198    uint8_t msg[20];
2199    uint8_t msg_len, dp_msg_len;
2200    int ret;
2201
2202    msg_len = 4;
2203    dp_msg_len = 4;
2204    msg[0] = address;
2205    msg[1] = address >> 8;
2206    msg[2] = AUX_NATIVE_READ << 4;
2207    msg[3] = (dp_msg_len) << 4;
2208    msg[3] |= expected_bytes - 1;
2209
2210    if (0)
2211	ErrorF("reading %02x %02x %02x, %d, %d\n", msg[0], msg[1], msg[3], expected_bytes, dp_msg_len);
2212    ret = RADEONProcessAuxCH(output, msg, msg_len, read_p, expected_bytes, delay);
2213    return ret;
2214}
2215
2216/* fill out the DPCD structure */
2217void RADEON_DP_GetDPCD(xf86OutputPtr output)
2218{
2219    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2220    uint8_t msg[25];
2221    int ret;
2222
2223    ret = atom_dp_aux_native_read(output, DP_DPCD_REV, 0, 8, msg);
2224    if (ret) {
2225	memcpy(radeon_output->dpcd, msg, 8);
2226	if (0) {
2227	    int i;
2228	    ErrorF("DPCD: ");
2229	    for (i = 0; i < 8; i++)
2230		ErrorF("%02x ", radeon_output->dpcd[i]);
2231	    ErrorF("\n");
2232	}
2233	ret = atom_dp_aux_native_read(output, DP_LINK_BW_SET, 0, 2, msg);
2234	if (0) {
2235	    ErrorF("0x200: %02x %02x\n", msg[0], msg[1]);
2236	}
2237	return;
2238    }
2239    radeon_output->dpcd[0] = 0;
2240    return;
2241}
2242
2243
2244enum dp_aux_i2c_mode {
2245    dp_aux_i2c_start,
2246    dp_aux_i2c_write,
2247    dp_aux_i2c_read,
2248    dp_aux_i2c_stop,
2249};
2250
2251
2252static Bool atom_dp_aux_i2c_transaction(xf86OutputPtr output, uint16_t address,
2253				       enum dp_aux_i2c_mode mode,
2254				       uint8_t write_byte, uint8_t *read_byte)
2255{
2256    uint8_t msg[8], msg_len, dp_msg_len;
2257    int ret;
2258    int auxch_cmd = 0;
2259
2260    memset(msg, 0, 8);
2261
2262    if (mode != dp_aux_i2c_stop)
2263	auxch_cmd = AUX_I2C_MOT;
2264
2265    if (address & 1)
2266	auxch_cmd |= AUX_I2C_READ;
2267    else
2268    	auxch_cmd |= AUX_I2C_WRITE;
2269
2270    msg[2] = auxch_cmd << 4;
2271
2272    msg[4] = 0;
2273    msg[0] = (address >> 1);
2274    msg[1] = (address >> 9);
2275
2276    msg_len = 4;
2277    dp_msg_len = 3;
2278    switch (mode) {
2279    case dp_aux_i2c_read:
2280	/* bottom bits is byte count - 1 so for 1 byte == 0 */
2281	dp_msg_len += 1;
2282	break;
2283    case dp_aux_i2c_write:
2284	dp_msg_len += 2;
2285	msg[4] = write_byte;
2286	msg_len++;
2287	break;
2288    default:
2289	break;
2290    }
2291    msg[3] = dp_msg_len << 4;
2292
2293    ret = RADEONProcessAuxCH(output, msg, msg_len, read_byte, 1, 0);
2294    return ret;
2295}
2296
2297static Bool
2298atom_dp_i2c_address(I2CDevPtr dev, I2CSlaveAddr addr)
2299{
2300    I2CBusPtr bus = dev->pI2CBus;
2301    xf86OutputPtr output = bus->DriverPrivate.ptr;
2302    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2303    int ret;
2304
2305    radeon_output->dp_i2c_addr = addr;
2306    radeon_output->dp_i2c_running = TRUE;
2307
2308    /* call i2c start */
2309    ret = atom_dp_aux_i2c_transaction(output, radeon_output->dp_i2c_addr,
2310				      dp_aux_i2c_start, 0, NULL);
2311
2312    return ret;
2313}
2314static Bool
2315atom_dp_i2c_start(I2CBusPtr bus, int timeout)
2316{
2317    ErrorF("%s\n", __func__);
2318    return TRUE;
2319}
2320
2321static void
2322atom_dp_i2c_stop(I2CDevPtr dev)
2323{
2324    I2CBusPtr bus = dev->pI2CBus;
2325    xf86OutputPtr output = bus->DriverPrivate.ptr;
2326    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2327
2328    if (radeon_output->dp_i2c_running)
2329	atom_dp_aux_i2c_transaction(output, radeon_output->dp_i2c_addr,
2330				    dp_aux_i2c_stop, 0, NULL);
2331    radeon_output->dp_i2c_running = FALSE;
2332}
2333
2334
2335static Bool
2336atom_dp_i2c_put_byte(I2CDevPtr dev, I2CByte byte)
2337{
2338    I2CBusPtr bus = dev->pI2CBus;
2339    xf86OutputPtr output = bus->DriverPrivate.ptr;
2340    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2341    Bool ret;
2342
2343    ret = (atom_dp_aux_i2c_transaction(output, radeon_output->dp_i2c_addr,
2344				       dp_aux_i2c_write, byte, NULL));
2345    return ret;
2346}
2347
2348static Bool
2349atom_dp_i2c_get_byte(I2CDevPtr dev, I2CByte *byte_ret, Bool last)
2350{
2351    I2CBusPtr bus = dev->pI2CBus;
2352    xf86OutputPtr output = bus->DriverPrivate.ptr;
2353    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2354    Bool ret;
2355
2356    ret = (atom_dp_aux_i2c_transaction(output, radeon_output->dp_i2c_addr,
2357				       dp_aux_i2c_read, 0, byte_ret));
2358    return ret;
2359}
2360
2361Bool
2362RADEON_DP_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, xf86OutputPtr output)
2363{
2364    I2CBusPtr pI2CBus;
2365
2366    pI2CBus = xf86CreateI2CBusRec();
2367    if (!pI2CBus) return FALSE;
2368
2369    pI2CBus->BusName = name;
2370    pI2CBus->scrnIndex = pScrn->scrnIndex;
2371    pI2CBus->I2CGetByte = atom_dp_i2c_get_byte;
2372    pI2CBus->I2CPutByte = atom_dp_i2c_put_byte;
2373    pI2CBus->I2CAddress = atom_dp_i2c_address;
2374    pI2CBus->I2CStart = atom_dp_i2c_start;
2375    pI2CBus->I2CStop = atom_dp_i2c_stop;
2376    pI2CBus->DriverPrivate.ptr = output;
2377
2378    /*
2379     * These were set incorrectly in the server pre-1.3, Having
2380     * duplicate settings is sub-optimal, but this lets the driver
2381     * work with older servers
2382     */
2383    pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
2384    pI2CBus->StartTimeout = 550;
2385    pI2CBus->BitTimeout = 40;
2386    pI2CBus->AcknTimeout = 40;
2387    pI2CBus->RiseFallTime = 20;
2388
2389    if (!xf86I2CBusInit(pI2CBus))
2390	return FALSE;
2391
2392    *bus_ptr = pI2CBus;
2393    return TRUE;
2394}
2395
2396
2397static uint8_t dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], int r)
2398{
2399    return link_status[r - DP_LANE0_1_STATUS];
2400}
2401
2402static uint8_t dp_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane)
2403{
2404    int i = DP_LANE0_1_STATUS + (lane >> 1);
2405    int s = (lane & 1) * 4;
2406    uint8_t l = dp_link_status(link_status, i);
2407    return (l >> s) & 0xf;
2408}
2409
2410static Bool dp_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
2411{
2412    int lane;
2413
2414    uint8_t lane_status;
2415
2416    for (lane = 0; lane < lane_count; lane++) {
2417	lane_status = dp_get_lane_status(link_status, lane);
2418	if ((lane_status & DP_LANE_CR_DONE) == 0)
2419	    return FALSE;
2420    }
2421    return TRUE;
2422}
2423
2424
2425/* Check to see if channel eq is done on all channels */
2426#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\
2427			 DP_LANE_CHANNEL_EQ_DONE|\
2428			 DP_LANE_SYMBOL_LOCKED)
2429static Bool
2430dp_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
2431{
2432    uint8_t lane_align;
2433    uint8_t lane_status;
2434    int lane;
2435
2436    lane_align = dp_link_status(link_status,
2437				DP_LANE_ALIGN_STATUS_UPDATED);
2438    if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
2439	return FALSE;
2440    for (lane = 0; lane < lane_count; lane++) {
2441	lane_status = dp_get_lane_status(link_status, lane);
2442	if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
2443	    return FALSE;
2444    }
2445    return TRUE;
2446}
2447
2448/*
2449 * Fetch AUX CH registers 0x202 - 0x207 which contain
2450 * link status information
2451 */
2452static Bool
2453atom_dp_get_link_status(xf86OutputPtr output,
2454			  uint8_t link_status[DP_LINK_STATUS_SIZE])
2455{
2456    ScrnInfoPtr pScrn = output->scrn;
2457    int ret;
2458    ret = atom_dp_aux_native_read(output, DP_LANE0_1_STATUS, 100,
2459				  DP_LINK_STATUS_SIZE, link_status);
2460    if (!ret) {
2461	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "dp link status failed\n");
2462	return FALSE;
2463    }
2464    ErrorF("link status %02x %02x %02x %02x %02x %02x\n", link_status[0], link_status[1],
2465	   link_status[2], link_status[3], link_status[4], link_status[5]);
2466
2467    return TRUE;
2468}
2469
2470static uint8_t
2471dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
2472			      int lane)
2473
2474{
2475    int     i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
2476    int     s = ((lane & 1) ?
2477                 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
2478                 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
2479    uint8_t l = dp_link_status(link_status, i);
2480
2481    return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
2482}
2483
2484static uint8_t
2485dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
2486				   int lane)
2487{
2488    int     i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
2489    int     s = ((lane & 1) ?
2490                 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
2491                 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
2492    uint8_t l = dp_link_status(link_status, i);
2493
2494    return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
2495}
2496
2497static char     *voltage_names[] = {
2498        "0.4V", "0.6V", "0.8V", "1.2V"
2499};
2500static char     *pre_emph_names[] = {
2501        "0dB", "3.5dB", "6dB", "9.5dB"
2502};
2503
2504/*
2505 * These are source-specific values; current Intel hardware supports
2506 * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
2507 */
2508#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
2509
2510static uint8_t
2511dp_pre_emphasis_max(uint8_t voltage_swing)
2512{
2513    switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
2514    case DP_TRAIN_VOLTAGE_SWING_400:
2515        return DP_TRAIN_PRE_EMPHASIS_6;
2516    case DP_TRAIN_VOLTAGE_SWING_600:
2517        return DP_TRAIN_PRE_EMPHASIS_6;
2518    case DP_TRAIN_VOLTAGE_SWING_800:
2519        return DP_TRAIN_PRE_EMPHASIS_3_5;
2520    case DP_TRAIN_VOLTAGE_SWING_1200:
2521    default:
2522        return DP_TRAIN_PRE_EMPHASIS_0;
2523    }
2524}
2525
2526static void dp_set_training(xf86OutputPtr output, uint8_t training)
2527{
2528    atom_dp_aux_native_write(output, DP_TRAINING_PATTERN_SET, 1, &training);
2529}
2530
2531static void dp_set_power(xf86OutputPtr output, uint8_t power_state)
2532{
2533    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2534
2535    if (radeon_output->dpcd[0] >= 0x11) {
2536	atom_dp_aux_native_write(output, 0x600, 1, &power_state);
2537    }
2538}
2539
2540static void
2541dp_get_adjust_train(xf86OutputPtr output,
2542		      uint8_t link_status[DP_LINK_STATUS_SIZE],
2543		      int lane_count,
2544		      uint8_t train_set[4])
2545{
2546    ScrnInfoPtr pScrn = output->scrn;
2547    uint8_t v = 0;
2548    uint8_t p = 0;
2549    int lane;
2550
2551    for (lane = 0; lane < lane_count; lane++) {
2552	uint8_t this_v = dp_get_adjust_request_voltage(link_status, lane);
2553	uint8_t this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);
2554
2555	if (0) {
2556	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2557		       "requested signal parameters: lane %d voltage %s pre_emph %s\n",
2558		       lane,
2559		       voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
2560		       pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
2561	}
2562	if (this_v > v)
2563	    v = this_v;
2564	if (this_p > p)
2565	    p = this_p;
2566    }
2567
2568    if (v >= DP_VOLTAGE_MAX)
2569	v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
2570
2571    if (p >= dp_pre_emphasis_max(v))
2572	p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
2573
2574    if (0) {
2575	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2576		   "using signal parameters: voltage %s pre_emph %s\n",
2577		   voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
2578		   pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
2579    }
2580    for (lane = 0; lane < 4; lane++)
2581	train_set[lane] = v | p;
2582}
2583
2584static int radeon_dp_max_lane_count(xf86OutputPtr output)
2585{
2586    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2587    int max_lane_count = 4;
2588
2589    if (radeon_output->dpcd[0] >= 0x11) {
2590	max_lane_count = radeon_output->dpcd[2] & 0x1f;
2591	switch(max_lane_count) {
2592	case 1: case 2: case 4:
2593	    break;
2594	default:
2595	    max_lane_count = 4;
2596	}
2597    }
2598    return max_lane_count;
2599}
2600
2601Bool radeon_dp_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
2602{
2603	RADEONOutputPrivatePtr radeon_output = output->driver_private;
2604	int clock = adjusted_mode->Clock;
2605
2606	radeon_output->dp_lane_count = dp_lanes_for_mode_clock(output, clock);
2607	radeon_output->dp_clock = dp_link_clock_for_mode_clock(output, clock);
2608	if (!radeon_output->dp_lane_count || !radeon_output->dp_clock)
2609		return FALSE;
2610	return TRUE;
2611}
2612
2613static void dp_update_dpvs_emph(xf86OutputPtr output, uint8_t train_set[4])
2614{
2615    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2616    int i;
2617    for (i = 0; i < radeon_output->dp_lane_count; i++)
2618	atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, i, train_set[i]);
2619
2620    atom_dp_aux_native_write(output, DP_TRAINING_LANE0_SET, radeon_output->dp_lane_count, train_set);
2621}
2622
2623static void do_displayport_link_train(xf86OutputPtr output)
2624{
2625    ScrnInfoPtr pScrn = output->scrn;
2626    RADEONInfoPtr info = RADEONPTR(pScrn);
2627    RADEONOutputPrivatePtr radeon_output = output->driver_private;
2628    int enc_id = atom_dp_get_encoder_id(output);
2629    Bool clock_recovery;
2630    uint8_t link_status[DP_LINK_STATUS_SIZE];
2631    uint8_t tries, voltage, ss_cntl;
2632    uint8_t train_set[4];
2633    int i;
2634    Bool channel_eq;
2635    uint8_t dp_link_configuration[DP_LINK_CONFIGURATION_SIZE];
2636
2637    memset(train_set, 0, 4);
2638
2639    /* set up link configuration */
2640    memset(dp_link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
2641
2642    if (radeon_output->dp_clock == 27000)
2643	dp_link_configuration[0] = DP_LINK_BW_2_7;
2644    else
2645	dp_link_configuration[0] = DP_LINK_BW_1_62;
2646    dp_link_configuration[1] = radeon_output->dp_lane_count;
2647
2648    if (radeon_output->dpcd[0] >= 0x11) {
2649	dp_link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
2650    }
2651
2652    /* power up to D0 */
2653    dp_set_power(output, DP_SET_POWER_D0);
2654
2655    /* disable training */
2656    dp_set_training(output, DP_TRAINING_PATTERN_DISABLE);
2657
2658    /* write link rate / num / eh framing */
2659    atom_dp_aux_native_write(output, DP_LINK_BW_SET, 2,
2660			     dp_link_configuration);
2661
2662    /* write ss cntl */
2663    ss_cntl = 0;
2664    atom_dp_aux_native_write(output, DP_DOWNSPREAD_CTRL, 1,
2665			     &ss_cntl);
2666
2667    /* start local training start */
2668    if (IS_DCE4_VARIANT) {
2669	atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
2670	atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
2671    } else {
2672	RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_START, enc_id, 0);
2673	RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, enc_id, 0);
2674    }
2675
2676    usleep(400);
2677    dp_set_training(output, DP_TRAINING_PATTERN_1);
2678    dp_update_dpvs_emph(output, train_set);
2679
2680    /* loop around doing configuration reads and DP encoder setups */
2681    clock_recovery = FALSE;
2682    tries = 0;
2683    voltage = 0xff;
2684    for (;;) {
2685      	usleep(100);
2686	if (!atom_dp_get_link_status(output, link_status))
2687	    break;
2688
2689	if (dp_clock_recovery_ok(link_status, radeon_output->dp_lane_count)) {
2690	    clock_recovery = TRUE;
2691	    break;
2692	}
2693
2694	for (i = 0; i < radeon_output->dp_lane_count; i++)
2695	    if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
2696		break;
2697	if (i == radeon_output->dp_lane_count) {
2698	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2699		       "clock recovery reached max voltage\n");
2700	    break;
2701	}
2702
2703	/* Check to see if we've tried the same voltage 5 times */
2704	if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
2705	    ++tries;
2706	    if (tries == 5) {
2707		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2708			   "clock recovery tried 5 times\n");
2709		break;
2710	    }
2711	} else
2712	    tries = 0;
2713
2714	voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
2715
2716        dp_get_adjust_train(output, link_status, radeon_output->dp_lane_count, train_set);
2717	dp_update_dpvs_emph(output, train_set);
2718
2719    }
2720
2721    if (!clock_recovery)
2722	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2723		   "clock recovery failed\n");
2724
2725    /* channel equalization */
2726    tries = 0;
2727    channel_eq = FALSE;
2728    dp_set_training(output, DP_TRAINING_PATTERN_2);
2729    if (IS_DCE4_VARIANT)
2730	atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
2731    else
2732	RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, enc_id, 1);
2733
2734    for (;;) {
2735	usleep(400);
2736	if (!atom_dp_get_link_status(output, link_status))
2737	    break;
2738
2739	if (dp_channel_eq_ok(link_status, radeon_output->dp_lane_count)) {
2740	    channel_eq = TRUE;
2741	    break;
2742	}
2743
2744	/* Try 5 times */
2745	if (tries > 5) {
2746	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2747		       "channel eq failed: 5 tries\n");
2748	    break;
2749	}
2750
2751	/* Compute new train_set as requested by target */
2752        dp_get_adjust_train(output, link_status, radeon_output->dp_lane_count, train_set);
2753	dp_update_dpvs_emph(output, train_set);
2754
2755	++tries;
2756    }
2757
2758    if (!channel_eq)
2759	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2760		   "channel eq failed\n");
2761
2762    dp_set_training(output, DP_TRAINING_PATTERN_DISABLE);
2763    if (IS_DCE4_VARIANT)
2764	atombios_output_dig_encoder_setup(output, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
2765    else
2766	RADEONDPEncoderService(output, ATOM_DP_ACTION_TRAINING_COMPLETE, enc_id, 0);
2767
2768}
2769
2770