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