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