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