2 * Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Alexander von Gluck, kallisti5@unixzen.com
17 #include "accelerant.h"
18 #include "accelerant_protos.h"
20 #include "connector.h"
22 #include "displayport.h"
28 extern "C" void _sPrintf(const char* format
, ...);
29 # define TRACE(x...) _sPrintf("radeon_hd: " x)
31 # define TRACE(x...) ;
34 #define ERROR(x...) _sPrintf("radeon_hd: " x)
40 TRACE("%s: called\n", __func__
);
41 radeon_shared_info
&info
= *gInfo
->shared_info
;
43 for (uint32 id
= 0; id
< ATOM_MAX_SUPPORTED_DEVICE
; id
++) {
44 if (gConnector
[id
]->valid
== false)
47 switch (gConnector
[id
]->encoder
.objectID
) {
48 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
49 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
50 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
51 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
52 transmitter_dig_setup(id
, 0, 0, 0,
53 ATOM_TRANSMITTER_ACTION_INIT
);
59 if ((info
.chipsetFlags
& CHIP_APU
) != 0) {
60 if (gConnector
[id
]->encoderExternal
.valid
== true) {
61 encoder_external_setup(id
,
62 EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT
);
70 encoder_assign_crtc(uint8 crtcID
)
72 TRACE("%s\n", __func__
);
74 int index
= GetIndexIntoMasterTable(COMMAND
, SelectCRTC_Source
);
79 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
83 TRACE("%s: table %" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
84 tableMajor
, tableMinor
);
86 uint16 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
87 uint16 connectorFlags
= gConnector
[connectorIndex
]->flags
;
88 uint16 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
90 // Prepare AtomBIOS command arguments
91 union crtcSourceParam
{
92 SELECT_CRTC_SOURCE_PS_ALLOCATION v1
;
93 SELECT_CRTC_SOURCE_PARAMETERS_V2 v2
;
95 union crtcSourceParam args
;
96 memset(&args
, 0, sizeof(args
));
100 switch (tableMinor
) {
103 args
.v1
.ucCRTC
= crtcID
;
105 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
106 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
107 args
.v1
.ucDevice
= ATOM_DEVICE_DFP1_INDEX
;
109 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
110 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
111 if ((gConnector
[connectorIndex
]->flags
112 & ATOM_DEVICE_LCD1_SUPPORT
) != 0)
113 args
.v1
.ucDevice
= ATOM_DEVICE_LCD1_INDEX
;
115 args
.v1
.ucDevice
= ATOM_DEVICE_DFP3_INDEX
;
117 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
118 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
119 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
120 args
.v1
.ucDevice
= ATOM_DEVICE_DFP2_INDEX
;
122 case ENCODER_OBJECT_ID_INTERNAL_DAC1
:
123 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
125 & ATOM_DEVICE_TV_SUPPORT
) != 0) {
126 args
.v1
.ucDevice
= ATOM_DEVICE_TV1_INDEX
;
127 } else if ((connectorFlags
128 & ATOM_DEVICE_CV_SUPPORT
) != 0) {
129 args
.v1
.ucDevice
= ATOM_DEVICE_CV_INDEX
;
131 args
.v1
.ucDevice
= ATOM_DEVICE_CRT1_INDEX
;
133 case ENCODER_OBJECT_ID_INTERNAL_DAC2
:
134 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
136 & ATOM_DEVICE_TV_SUPPORT
) != 0) {
137 args
.v1
.ucDevice
= ATOM_DEVICE_TV1_INDEX
;
138 } else if ((connectorFlags
139 & ATOM_DEVICE_CV_SUPPORT
) != 0) {
140 args
.v1
.ucDevice
= ATOM_DEVICE_CV_INDEX
;
142 args
.v1
.ucDevice
= ATOM_DEVICE_CRT2_INDEX
;
147 args
.v2
.ucCRTC
= crtcID
;
149 = display_get_encoder_mode(connectorIndex
);
151 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
152 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
153 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
154 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
155 switch (encoder_pick_dig(connectorIndex
)) {
158 = ASIC_INT_DIG1_ENCODER_ID
;
162 = ASIC_INT_DIG2_ENCODER_ID
;
166 = ASIC_INT_DIG3_ENCODER_ID
;
170 = ASIC_INT_DIG4_ENCODER_ID
;
174 = ASIC_INT_DIG5_ENCODER_ID
;
178 = ASIC_INT_DIG6_ENCODER_ID
;
182 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
183 args
.v2
.ucEncoderID
= ASIC_INT_DVO_ENCODER_ID
;
185 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
187 & ATOM_DEVICE_TV_SUPPORT
) != 0) {
188 args
.v2
.ucEncoderID
= ASIC_INT_TV_ENCODER_ID
;
189 } else if ((connectorFlags
190 & ATOM_DEVICE_CV_SUPPORT
) != 0) {
191 args
.v2
.ucEncoderID
= ASIC_INT_TV_ENCODER_ID
;
193 args
.v2
.ucEncoderID
= ASIC_INT_DAC1_ENCODER_ID
;
195 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
197 & ATOM_DEVICE_TV_SUPPORT
) != 0) {
198 args
.v2
.ucEncoderID
= ASIC_INT_TV_ENCODER_ID
;
199 } else if ((connectorFlags
200 & ATOM_DEVICE_CV_SUPPORT
) != 0) {
201 args
.v2
.ucEncoderID
= ASIC_INT_TV_ENCODER_ID
;
203 args
.v2
.ucEncoderID
= ASIC_INT_DAC2_ENCODER_ID
;
210 ERROR("%s: Unknown table version: %" B_PRIu8
".%" B_PRIu8
"\n",
211 __func__
, tableMajor
, tableMinor
);
215 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
217 // update crtc encoder scratch register @ scratch 3
218 encoder_crtc_scratch(crtcID
);
223 encoder_pick_dig(uint32 connectorIndex
)
225 TRACE("%s\n", __func__
);
226 radeon_shared_info
&info
= *gInfo
->shared_info
;
227 uint32 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
229 // obtain assigned CRT
231 for (crtcID
= 0; crtcID
< MAX_DISPLAY
; crtcID
++) {
232 if (gDisplay
[crtcID
]->attached
!= true)
234 if (gDisplay
[crtcID
]->connectorIndex
== connectorIndex
)
238 bool linkB
= gConnector
[connectorIndex
]->encoder
.linkEnumeration
239 == GRAPH_OBJECT_ENUM_ID2
? true : false;
241 uint32 dceVersion
= (info
.dceMajor
* 100) + info
.dceMinor
;
243 if (dceVersion
>= 400) {
245 switch (info
.chipsetID
) {
247 return linkB
? 1 : 0;
254 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
255 return linkB
? 1 : 0;
256 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
257 return linkB
? 3 : 2;
258 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
259 return linkB
? 5 : 4;
263 if (dceVersion
>= 302)
266 if (encoderID
== ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
)
274 encoder_apply_quirks(uint8 crtcID
)
276 TRACE("%s\n", __func__
);
277 radeon_shared_info
&info
= *gInfo
->shared_info
;
278 register_info
* regs
= gDisplay
[crtcID
]->regs
;
279 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
280 uint16 connectorFlags
= gConnector
[connectorIndex
]->flags
;
282 // Setting the scaler clears this on some chips...
283 if (info
.dceMajor
>= 3
284 && (connectorFlags
& ATOM_DEVICE_TV_SUPPORT
) == 0) {
285 // TODO: assume non interleave mode for now
286 // en: EVERGREEN_INTERLEAVE_EN : AVIVO_D1MODE_INTERLEAVE_EN
287 Write32(OUT
, regs
->modeDataFormat
, 0);
293 encoder_mode_set(uint8 crtcID
)
295 TRACE("%s\n", __func__
);
296 radeon_shared_info
&info
= *gInfo
->shared_info
;
297 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
298 uint16 connectorFlags
= gConnector
[connectorIndex
]->flags
;
299 pll_info
* pll
= &gConnector
[connectorIndex
]->encoder
.pll
;
301 // TODO: Should this be the adjusted pll or the original?
302 uint32 pixelClock
= pll
->pixelClock
;
304 switch (gConnector
[connectorIndex
]->encoder
.objectID
) {
305 case ENCODER_OBJECT_ID_INTERNAL_DAC1
:
306 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
307 case ENCODER_OBJECT_ID_INTERNAL_DAC2
:
308 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
309 encoder_analog_setup(connectorIndex
, pixelClock
, ATOM_ENABLE
);
310 if (info
.dceMajor
< 5) {
311 // TV encoder was dropped in DCE 5
312 if ((connectorFlags
& ATOM_DEVICE_TV_SUPPORT
) != 0
313 || (connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0) {
314 encoder_tv_setup(connectorIndex
, pixelClock
, ATOM_ENABLE
);
316 encoder_tv_setup(connectorIndex
, pixelClock
, ATOM_DISABLE
);
320 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
321 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
322 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
323 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
324 encoder_digital_setup(connectorIndex
, pixelClock
,
325 PANEL_ENCODER_ACTION_ENABLE
);
327 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
328 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
329 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
330 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
331 if ((info
.chipsetFlags
& CHIP_APU
) != 0
332 || info
.dceMajor
>= 5) {
334 encoder_dig_setup(connectorIndex
, pixelClock
,
335 ATOM_ENCODER_CMD_SETUP
);
336 encoder_dig_setup(connectorIndex
, pixelClock
,
337 ATOM_ENCODER_CMD_SETUP_PANEL_MODE
);
338 } else if (info
.dceMajor
>= 4) {
339 // Disable DIG transmitter
340 transmitter_dig_setup(connectorIndex
, pixelClock
, 0, 0,
341 ATOM_TRANSMITTER_ACTION_DISABLE
);
343 encoder_dig_setup(connectorIndex
, pixelClock
,
344 ATOM_ENCODER_CMD_SETUP
);
345 // Enable DIG transmitter
346 transmitter_dig_setup(connectorIndex
, pixelClock
, 0, 0,
347 ATOM_TRANSMITTER_ACTION_ENABLE
);
349 // Disable DIG transmitter
350 transmitter_dig_setup(connectorIndex
, pixelClock
, 0, 0,
351 ATOM_TRANSMITTER_ACTION_DISABLE
);
352 // Disable DIG encoder
353 encoder_dig_setup(connectorIndex
, pixelClock
, ATOM_DISABLE
);
354 // Enable the DIG encoder
355 encoder_dig_setup(connectorIndex
, pixelClock
, ATOM_ENABLE
);
357 // Setup and enable DIG transmitter
358 transmitter_dig_setup(connectorIndex
, pixelClock
, 0, 0,
359 ATOM_TRANSMITTER_ACTION_SETUP
);
360 transmitter_dig_setup(connectorIndex
, pixelClock
, 0, 0,
361 ATOM_TRANSMITTER_ACTION_ENABLE
);
364 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
365 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
366 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
367 TRACE("%s: TODO for DVO encoder setup\n", __func__
);
371 if (gConnector
[connectorIndex
]->encoderExternal
.valid
== true) {
372 if ((info
.chipsetFlags
& CHIP_APU
) != 0) {
374 encoder_external_setup(connectorIndex
,
375 EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP
);
377 encoder_external_setup(connectorIndex
, ATOM_ENABLE
);
381 encoder_apply_quirks(crtcID
);
386 encoder_tv_setup(uint32 connectorIndex
, uint32 pixelClock
, int command
)
388 uint16 connectorFlags
= gConnector
[connectorIndex
]->flags
;
390 TV_ENCODER_CONTROL_PS_ALLOCATION args
;
391 memset(&args
, 0, sizeof(args
));
393 int index
= GetIndexIntoMasterTable(COMMAND
, TVEncoderControl
);
395 args
.sTVEncoder
.ucAction
= command
;
397 if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0)
398 args
.sTVEncoder
.ucTvStandard
= ATOM_TV_CV
;
400 // TODO: we assume NTSC for now
401 args
.sTVEncoder
.ucTvStandard
= ATOM_TV_NTSC
;
404 args
.sTVEncoder
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
406 return atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
411 encoder_digital_setup(uint32 connectorIndex
, uint32 pixelClock
, int command
)
413 TRACE("%s\n", __func__
);
416 uint16 connectorFlags
= gConnector
[connectorIndex
]->flags
;
418 switch (gConnector
[connectorIndex
]->encoder
.objectID
) {
419 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
420 index
= GetIndexIntoMasterTable(COMMAND
, LVDSEncoderControl
);
422 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
423 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
424 index
= GetIndexIntoMasterTable(COMMAND
, TMDS1EncoderControl
);
426 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
427 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0)
428 index
= GetIndexIntoMasterTable(COMMAND
, LVDSEncoderControl
);
430 index
= GetIndexIntoMasterTable(COMMAND
, TMDS2EncoderControl
);
438 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
440 ERROR("%s: cannot parse command table\n", __func__
);
444 uint32 lvdsFlags
= gConnector
[connectorIndex
]->lvdsFlags
;
447 if (gConnector
[connectorIndex
]->type
== VIDEO_CONNECTOR_HDMIA
448 || gConnector
[connectorIndex
]->type
== VIDEO_CONNECTOR_HDMIB
) {
452 // Prepare AtomBIOS command arguments
453 union lvdsEncoderControl
{
454 LVDS_ENCODER_CONTROL_PS_ALLOCATION v1
;
455 LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2
;
457 union lvdsEncoderControl args
;
458 memset(&args
, 0, sizeof(args
));
460 TRACE("%s: table %" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
461 tableMajor
, tableMinor
);
463 switch (tableMajor
) {
466 switch (tableMinor
) {
469 args
.v1
.ucAction
= command
;
471 args
.v1
.ucMisc
|= PANEL_ENCODER_MISC_HDMI_TYPE
;
472 args
.v1
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
474 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0) {
475 if ((lvdsFlags
& ATOM_PANEL_MISC_DUAL
) != 0)
476 args
.v1
.ucMisc
|= PANEL_ENCODER_MISC_DUAL
;
477 if ((lvdsFlags
& ATOM_PANEL_MISC_888RGB
) != 0)
478 args
.v1
.ucMisc
|= ATOM_PANEL_MISC_888RGB
;
481 // args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
482 if (pixelClock
> 165000)
483 args
.v1
.ucMisc
|= PANEL_ENCODER_MISC_DUAL
;
484 /*if (pScrn->rgbBits == 8) */
485 args
.v1
.ucMisc
|= ATOM_PANEL_MISC_888RGB
;
491 args
.v2
.ucAction
= command
;
492 if (tableMinor
== 3) {
493 //if (dig->coherent_mode)
494 // args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
497 args
.v2
.ucMisc
|= PANEL_ENCODER_MISC_HDMI_TYPE
;
498 args
.v2
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
499 args
.v2
.ucTruncate
= 0;
500 args
.v2
.ucSpatial
= 0;
501 args
.v2
.ucTemporal
= 0;
503 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0) {
504 if ((lvdsFlags
& ATOM_PANEL_MISC_DUAL
) != 0)
505 args
.v2
.ucMisc
|= PANEL_ENCODER_MISC_DUAL
;
506 if ((lvdsFlags
& ATOM_PANEL_MISC_SPATIAL
) != 0) {
507 args
.v2
.ucSpatial
= PANEL_ENCODER_SPATIAL_DITHER_EN
;
508 if ((lvdsFlags
& ATOM_PANEL_MISC_888RGB
) != 0) {
510 |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH
;
514 if ((lvdsFlags
& ATOM_PANEL_MISC_TEMPORAL
) != 0) {
515 args
.v2
.ucTemporal
= PANEL_ENCODER_TEMPORAL_DITHER_EN
;
516 if ((lvdsFlags
& ATOM_PANEL_MISC_888RGB
) != 0) {
518 |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH
;
520 if (((lvdsFlags
>> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT
)
523 |= PANEL_ENCODER_TEMPORAL_LEVEL_4
;
528 // args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
529 if (pixelClock
> 165000)
530 args
.v2
.ucMisc
|= PANEL_ENCODER_MISC_DUAL
;
534 ERROR("%s: Unknown minor table version: %"
535 B_PRIu8
".%" B_PRIu8
"\n", __func__
,
536 tableMajor
, tableMinor
);
541 ERROR("%s: Unknown major table version: %" B_PRIu8
".%" B_PRIu8
"\n",
542 __func__
, tableMajor
, tableMinor
);
545 return atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
550 encoder_dig_setup(uint32 connectorIndex
, uint32 pixelClock
, int command
)
552 radeon_shared_info
&info
= *gInfo
->shared_info
;
553 connector_info
* connector
= gConnector
[connectorIndex
];
556 if (info
.dceMajor
>= 4)
557 index
= GetIndexIntoMasterTable(COMMAND
, DIGxEncoderControl
);
559 if (encoder_pick_dig(connectorIndex
))
560 index
= GetIndexIntoMasterTable(COMMAND
, DIG2EncoderControl
);
562 index
= GetIndexIntoMasterTable(COMMAND
, DIG1EncoderControl
);
569 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
571 ERROR("%s: cannot parse command table\n", __func__
);
575 // Prepare AtomBIOS command arguments
576 union digEncoderControl
{
577 DIG_ENCODER_CONTROL_PS_ALLOCATION v1
;
578 DIG_ENCODER_CONTROL_PARAMETERS_V2 v2
;
579 DIG_ENCODER_CONTROL_PARAMETERS_V3 v3
;
580 DIG_ENCODER_CONTROL_PARAMETERS_V4 v4
;
582 union digEncoderControl args
;
583 memset(&args
, 0, sizeof(args
));
585 bool isDPBridge
= connector
->encoderExternal
.isDPBridge
;
586 bool linkB
= connector
->encoder
.linkEnumeration
587 == GRAPH_OBJECT_ENUM_ID2
? true : false;
588 uint32 digEncoderID
= encoder_pick_dig(connectorIndex
);
590 uint32 panelMode
= 0;
591 // determine DP panel mode if doing panel mode setup
592 if (command
== ATOM_ENCODER_CMD_SETUP_PANEL_MODE
) {
593 if (info
.dceMajor
>= 4 && isDPBridge
) {
594 if (connector
->encoderExternal
.objectID
== ENCODER_OBJECT_ID_NUTMEG
)
595 panelMode
= DP_PANEL_MODE_INTERNAL_DP1_MODE
;
596 else if (connector
->encoderExternal
.objectID
597 == ENCODER_OBJECT_ID_TRAVIS
) {
598 dp_info
* dp
= &gConnector
[connectorIndex
]->dpInfo
;
601 for (bit
= 0; bit
< 6; bit
++)
602 id
[bit
] = dpcd_reg_read(dp
->auxPin
, 0x503 + bit
);
603 if (id
[0] == 0x73 && id
[1] == 0x69 && id
[2] == 0x76
604 && id
[3] == 0x61 && id
[4] == 0x72 && id
[5] == 0x54) {
605 panelMode
= DP_PANEL_MODE_INTERNAL_DP1_MODE
;
607 panelMode
= DP_PANEL_MODE_INTERNAL_DP2_MODE
;
610 panelMode
= DP_PANEL_MODE_INTERNAL_DP2_MODE
;
613 panelMode
= DP_PANEL_MODE_EXTERNAL_DP_MODE
;
617 uint32 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
618 if (gConnector
[connectorIndex
]->type
== VIDEO_CONNECTOR_EDP
) {
619 uint8 temp
= dpcd_read_reg(hwPin
, DP_EDP_CONFIGURATION_CAP
);
621 panelMode
= DP_PANEL_MODE_INTERNAL_DP2_MODE
;
625 TRACE("%s: table %" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
626 tableMajor
, tableMinor
);
628 dp_info
* dpInfo
= &gConnector
[connectorIndex
]->dpInfo
;
630 if (dpInfo
->valid
== true)
631 dpClock
= dpInfo
->linkRate
;
633 bool dualLink
= false;
634 if (connector
->type
== VIDEO_CONNECTOR_DVID
635 && pixelClock
> 165000) {
636 // TODO: Expand on this duallink code
640 // Careful! The mapping of ucHPD_ID differs between atombios calls
641 uint16 hpdID
= connector_pick_atom_hpdid(connectorIndex
);
643 switch (tableMinor
) {
645 args
.v1
.ucAction
= command
;
646 args
.v1
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
648 if (command
== ATOM_ENCODER_CMD_SETUP_PANEL_MODE
)
649 args
.v3
.ucPanelMode
= panelMode
;
651 args
.v1
.ucEncoderMode
652 = display_get_encoder_mode(connectorIndex
);
655 if (args
.v1
.ucEncoderMode
== ATOM_ENCODER_MODE_DP
656 || args
.v1
.ucEncoderMode
== ATOM_ENCODER_MODE_DP_MST
) {
657 args
.v1
.ucLaneNum
= dpInfo
->laneCount
;
659 args
.v1
.ucLaneNum
= 8;
661 args
.v1
.ucLaneNum
= 4;
663 if ((args
.v1
.ucEncoderMode
== ATOM_ENCODER_MODE_DP
664 || args
.v1
.ucEncoderMode
== ATOM_ENCODER_MODE_DP_MST
)
665 && dpClock
== 270000) {
666 args
.v1
.ucConfig
|= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ
;
669 switch (connector
->encoder
.objectID
) {
670 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
671 args
.v1
.ucConfig
= ATOM_ENCODER_CONFIG_V2_TRANSMITTER1
;
673 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
674 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
675 args
.v1
.ucConfig
= ATOM_ENCODER_CONFIG_V2_TRANSMITTER2
;
677 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
678 args
.v1
.ucConfig
= ATOM_ENCODER_CONFIG_V2_TRANSMITTER3
;
683 args
.v1
.ucConfig
|= ATOM_ENCODER_CONFIG_LINKB
;
685 args
.v1
.ucConfig
|= ATOM_ENCODER_CONFIG_LINKA
;
689 args
.v3
.ucAction
= command
;
690 args
.v3
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
692 if (command
== ATOM_ENCODER_CMD_SETUP_PANEL_MODE
)
693 args
.v3
.ucPanelMode
= panelMode
;
695 args
.v3
.ucEncoderMode
696 = display_get_encoder_mode(connectorIndex
);
699 if (args
.v3
.ucEncoderMode
== ATOM_ENCODER_MODE_DP
700 || args
.v3
.ucEncoderMode
== ATOM_ENCODER_MODE_DP_MST
) {
701 args
.v3
.ucLaneNum
= dpInfo
->laneCount
;
703 args
.v3
.ucLaneNum
= 8;
705 args
.v3
.ucLaneNum
= 4;
707 if ((args
.v3
.ucEncoderMode
== ATOM_ENCODER_MODE_DP
708 || args
.v3
.ucEncoderMode
== ATOM_ENCODER_MODE_DP_MST
)
709 && dpClock
== 270000) {
710 args
.v1
.ucConfig
|= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ
;
713 args
.v3
.acConfig
.ucDigSel
= encoder_pick_dig(connectorIndex
);
718 args
.v3
.ucBitPerColor
= PANEL_BPC_UNDEFINE
;
721 args
.v3
.ucBitPerColor
= PANEL_6BIT_PER_COLOR
;
725 args
.v3
.ucBitPerColor
= PANEL_8BIT_PER_COLOR
;
728 args
.v3
.ucBitPerColor
= PANEL_10BIT_PER_COLOR
;
731 args
.v3
.ucBitPerColor
= PANEL_12BIT_PER_COLOR
;
734 args
.v3
.ucBitPerColor
= PANEL_16BIT_PER_COLOR
;
739 args
.v4
.ucAction
= command
;
740 args
.v4
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
742 if (command
== ATOM_ENCODER_CMD_SETUP_PANEL_MODE
)
743 args
.v4
.ucPanelMode
= panelMode
;
745 args
.v4
.ucEncoderMode
746 = display_get_encoder_mode(connectorIndex
);
749 if (args
.v4
.ucEncoderMode
== ATOM_ENCODER_MODE_DP
750 || args
.v4
.ucEncoderMode
== ATOM_ENCODER_MODE_DP_MST
) {
752 args
.v4
.ucLaneNum
= dpInfo
->laneCount
;
753 if (dpClock
== 270000) {
755 |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ
;
756 } else if (dpClock
== 540000) {
758 |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ
;
760 } else if (dualLink
) {
761 // DualLink, double the lane numbers
762 args
.v4
.ucLaneNum
= 8;
764 args
.v4
.ucLaneNum
= 4;
766 args
.v4
.acConfig
.ucDigSel
= digEncoderID
;
771 args
.v4
.ucBitPerColor
= PANEL_BPC_UNDEFINE
;
774 args
.v4
.ucBitPerColor
= PANEL_6BIT_PER_COLOR
;
778 args
.v4
.ucBitPerColor
= PANEL_8BIT_PER_COLOR
;
781 args
.v4
.ucBitPerColor
= PANEL_10BIT_PER_COLOR
;
784 args
.v4
.ucBitPerColor
= PANEL_12BIT_PER_COLOR
;
787 args
.v4
.ucBitPerColor
= PANEL_16BIT_PER_COLOR
;
792 args
.v4
.ucHPD_ID
= 0;
794 args
.v4
.ucHPD_ID
= hpdID
+ 1;
797 ERROR("%s: unknown tableMinor!\n", __func__
);
800 status_t result
= atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
803 if (gConnector
[connectorIndex
]->type
== VIDEO_CONNECTOR_EDP
804 && panelMode
== DP_PANEL_MODE_INTERNAL_DP2_MODE
) {
805 dpcd_write_reg(hwPin
, DP_EDP_CONFIGURATION_SET
, 1);
814 encoder_external_setup(uint32 connectorIndex
, int command
)
816 TRACE("%s\n", __func__
);
818 encoder_info
* encoder
819 = &gConnector
[connectorIndex
]->encoder
;
820 encoder_info
* extEncoder
821 = &gConnector
[connectorIndex
]->encoderExternal
;
822 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
825 = &gConnector
[connectorIndex
]->dpInfo
;
827 if (extEncoder
->valid
!= true) {
828 ERROR("%s: connector %" B_PRIu32
" doesn't have a valid "
829 "external encoder!", __func__
, connectorIndex
);
836 int index
= GetIndexIntoMasterTable(COMMAND
, ExternalEncoderControl
);
837 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
839 ERROR("%s: Error parsing ExternalEncoderControl table\n", __func__
);
843 // Prepare AtomBIOS command arguments
844 union externalEncoderControl
{
845 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1
;
846 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3
;
848 union externalEncoderControl args
;
849 memset(&args
, 0, sizeof(args
));
851 int connectorObjectID
852 = (gConnector
[connectorIndex
]->objectID
& OBJECT_ID_MASK
)
855 uint32 pixelClock
= encoder
->pll
.pixelClock
;
857 TRACE("%s: table %" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
858 tableMajor
, tableMinor
);
859 switch (tableMajor
) {
861 // no options needed on table 1.x
864 switch (tableMinor
) {
867 args
.v1
.sDigEncoder
.ucAction
= command
;
868 args
.v1
.sDigEncoder
.usPixelClock
869 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
870 args
.v1
.sDigEncoder
.ucEncoderMode
871 = display_get_encoder_mode(connectorIndex
);
873 if (connector_is_dp(connectorIndex
)) {
874 if (dpInfo
->linkRate
== 270000) {
875 args
.v1
.sDigEncoder
.ucConfig
876 |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ
;
878 args
.v1
.sDigEncoder
.ucLaneNum
880 } else if (pixelClock
> 165000) {
881 args
.v1
.sDigEncoder
.ucLaneNum
= 8;
883 args
.v1
.sDigEncoder
.ucLaneNum
= 4;
888 args
.v3
.sExtEncoder
.ucAction
= command
;
889 if (command
== EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT
) {
890 args
.v3
.sExtEncoder
.usConnectorId
891 = B_HOST_TO_LENDIAN_INT16(connectorObjectID
);
893 args
.v3
.sExtEncoder
.usPixelClock
894 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
897 args
.v3
.sExtEncoder
.ucEncoderMode
898 = display_get_encoder_mode(connectorIndex
);
900 if (connector_is_dp(connectorIndex
)) {
901 if (dpInfo
->linkRate
== 270000) {
902 args
.v3
.sExtEncoder
.ucConfig
903 |=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ
;
904 } else if (dpInfo
->linkRate
== 540000) {
905 args
.v3
.sExtEncoder
.ucConfig
906 |=EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ
;
908 args
.v1
.sDigEncoder
.ucLaneNum
910 } else if (pixelClock
> 165000) {
911 args
.v3
.sExtEncoder
.ucLaneNum
= 8;
913 args
.v3
.sExtEncoder
.ucLaneNum
= 4;
916 switch ((connectorFlags
& ENUM_ID_MASK
) >> ENUM_ID_SHIFT
) {
917 case GRAPH_OBJECT_ENUM_ID1
:
918 TRACE("%s: external encoder 1\n", __func__
);
919 args
.v3
.sExtEncoder
.ucConfig
920 |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1
;
922 case GRAPH_OBJECT_ENUM_ID2
:
923 TRACE("%s: external encoder 2\n", __func__
);
924 args
.v3
.sExtEncoder
.ucConfig
925 |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2
;
927 case GRAPH_OBJECT_ENUM_ID3
:
928 TRACE("%s: external encoder 3\n", __func__
);
929 args
.v3
.sExtEncoder
.ucConfig
930 |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3
;
934 // TODO: don't set statically
935 uint32 bitsPerColor
= 8;
936 switch (bitsPerColor
) {
938 args
.v3
.sExtEncoder
.ucBitPerColor
939 = PANEL_BPC_UNDEFINE
;
942 args
.v3
.sExtEncoder
.ucBitPerColor
943 = PANEL_6BIT_PER_COLOR
;
947 args
.v3
.sExtEncoder
.ucBitPerColor
948 = PANEL_8BIT_PER_COLOR
;
951 args
.v3
.sExtEncoder
.ucBitPerColor
952 = PANEL_10BIT_PER_COLOR
;
955 args
.v3
.sExtEncoder
.ucBitPerColor
956 = PANEL_12BIT_PER_COLOR
;
959 args
.v3
.sExtEncoder
.ucBitPerColor
960 = PANEL_16BIT_PER_COLOR
;
966 ERROR("%s: Unknown table minor version: "
967 "%" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
968 tableMajor
, tableMinor
);
973 ERROR("%s: Unknown table major version: "
974 "%" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
975 tableMajor
, tableMinor
);
979 return atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
984 encoder_analog_setup(uint32 connectorIndex
, uint32 pixelClock
, int command
)
986 TRACE("%s\n", __func__
);
988 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
991 DAC_ENCODER_CONTROL_PS_ALLOCATION args
;
992 memset(&args
, 0, sizeof(args
));
994 switch (gConnector
[connectorIndex
]->encoder
.objectID
) {
995 case ENCODER_OBJECT_ID_INTERNAL_DAC1
:
996 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
997 index
= GetIndexIntoMasterTable(COMMAND
, DAC1EncoderControl
);
999 case ENCODER_OBJECT_ID_INTERNAL_DAC2
:
1000 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
1001 index
= GetIndexIntoMasterTable(COMMAND
, DAC2EncoderControl
);
1005 args
.ucAction
= command
;
1007 if ((connectorFlags
& ATOM_DEVICE_CRT_SUPPORT
) != 0)
1008 args
.ucDacStandard
= ATOM_DAC1_PS2
;
1009 else if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0)
1010 args
.ucDacStandard
= ATOM_DAC1_CV
;
1012 TRACE("%s: TODO, hardcoded NTSC TV support\n", __func__
);
1014 // NTSC, NTSC_J, PAL 60
1015 args
.ucDacStandard
= ATOM_DAC1_NTSC
;
1017 // PAL, SCART. SECAM, PAL_CN
1018 args
.ucDacStandard
= ATOM_DAC1_PAL
;
1022 args
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1024 return atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1029 encoder_analog_load_detect(uint32 connectorIndex
)
1031 TRACE("%s\n", __func__
);
1033 if (gConnector
[connectorIndex
]->encoderExternal
.valid
== true)
1034 return encoder_dig_load_detect(connectorIndex
);
1036 return encoder_dac_load_detect(connectorIndex
);
1041 encoder_dac_load_detect(uint32 connectorIndex
)
1043 TRACE("%s\n", __func__
);
1045 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1046 uint32 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
1048 if ((connectorFlags
& ATOM_DEVICE_TV_SUPPORT
) == 0
1049 && (connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) == 0
1050 && (connectorFlags
& ATOM_DEVICE_CRT_SUPPORT
) == 0) {
1051 ERROR("%s: executed on non-dac device connector #%" B_PRIu8
"\n",
1052 __func__
, connectorIndex
);
1056 // *** tell the card we want to do a DAC detection
1058 DAC_LOAD_DETECTION_PS_ALLOCATION args
;
1059 int index
= GetIndexIntoMasterTable(COMMAND
, DAC_LoadDetection
);
1063 memset(&args
, 0, sizeof(args
));
1065 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
1067 ERROR("%s: failed getting AtomBIOS header for DAC_LoadDetection\n",
1072 args
.sDacload
.ucMisc
= 0;
1074 if (encoderID
== ENCODER_OBJECT_ID_INTERNAL_DAC1
1075 || encoderID
== ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
) {
1076 args
.sDacload
.ucDacType
= ATOM_DAC_A
;
1078 args
.sDacload
.ucDacType
= ATOM_DAC_B
;
1081 if ((connectorFlags
& ATOM_DEVICE_CRT1_SUPPORT
) != 0) {
1082 args
.sDacload
.usDeviceID
1083 = B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT1_SUPPORT
);
1084 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1086 uint32 biosScratch0
= Read32(OUT
, R600_SCRATCH_REG0
);
1088 if ((biosScratch0
& ATOM_S0_CRT1_MASK
) != 0)
1091 } else if ((connectorFlags
& ATOM_DEVICE_CRT2_SUPPORT
) != 0) {
1092 args
.sDacload
.usDeviceID
1093 = B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT2_SUPPORT
);
1094 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1096 uint32 biosScratch0
= Read32(OUT
, R600_SCRATCH_REG0
);
1098 if ((biosScratch0
& ATOM_S0_CRT2_MASK
) != 0)
1101 } else if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0) {
1102 args
.sDacload
.usDeviceID
1103 = B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CV_SUPPORT
);
1104 if (tableMinor
>= 3)
1105 args
.sDacload
.ucMisc
= DAC_LOAD_MISC_YPrPb
;
1106 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1108 uint32 biosScratch0
= Read32(OUT
, R600_SCRATCH_REG0
);
1110 if ((biosScratch0
& (ATOM_S0_CV_MASK
| ATOM_S0_CV_MASK_A
)) != 0)
1113 } else if ((connectorFlags
& ATOM_DEVICE_TV1_SUPPORT
) != 0) {
1114 args
.sDacload
.usDeviceID
1115 = B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_TV1_SUPPORT
);
1116 if (tableMinor
>= 3)
1117 args
.sDacload
.ucMisc
= DAC_LOAD_MISC_YPrPb
;
1118 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1120 uint32 biosScratch0
= Read32(OUT
, R600_SCRATCH_REG0
);
1123 & (ATOM_S0_TV1_COMPOSITE
| ATOM_S0_TV1_COMPOSITE_A
)) != 0) {
1124 return true; /* Composite connected */
1125 } else if ((biosScratch0
1126 & (ATOM_S0_TV1_SVIDEO
| ATOM_S0_TV1_SVIDEO_A
)) != 0) {
1127 return true; /* S-Video connected */
1136 encoder_dig_load_detect(uint32 connectorIndex
)
1138 TRACE("%s\n", __func__
);
1139 radeon_shared_info
&info
= *gInfo
->shared_info
;
1141 if (info
.dceMajor
< 4) {
1142 ERROR("%s: Strange: External DIG encoder on DCE < 4?\n", __func__
);
1146 encoder_external_setup(connectorIndex
,
1147 EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION
);
1149 uint32 biosScratch0
= Read32(OUT
, R600_SCRATCH_REG0
);
1151 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1153 if ((connectorFlags
& ATOM_DEVICE_CRT1_SUPPORT
) != 0)
1154 if ((biosScratch0
& ATOM_S0_CRT1_MASK
) != 0)
1156 if ((connectorFlags
& ATOM_DEVICE_CRT2_SUPPORT
) != 0)
1157 if ((biosScratch0
& ATOM_S0_CRT2_MASK
) != 0)
1159 if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0)
1160 if ((biosScratch0
& (ATOM_S0_CV_MASK
| ATOM_S0_CV_MASK_A
)) != 0)
1162 if ((connectorFlags
& ATOM_DEVICE_TV1_SUPPORT
) != 0) {
1164 & (ATOM_S0_TV1_COMPOSITE
| ATOM_S0_TV1_COMPOSITE_A
)) != 0)
1165 return true; /* Composite connected */
1166 else if ((biosScratch0
1167 & (ATOM_S0_TV1_SVIDEO
| ATOM_S0_TV1_SVIDEO_A
)) != 0)
1168 return true; /* S-Video connected */
1176 transmitter_dig_setup(uint32 connectorIndex
, uint32 pixelClock
,
1177 uint8 laneNumber
, uint8 laneSet
, int command
)
1179 TRACE("%s\n", __func__
);
1181 uint16 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
1183 switch (encoderID
) {
1184 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
1185 index
= GetIndexIntoMasterTable(COMMAND
, DVOOutputControl
);
1187 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1188 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1189 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1190 index
= GetIndexIntoMasterTable(COMMAND
, UNIPHYTransmitterControl
);
1192 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
1193 index
= GetIndexIntoMasterTable(COMMAND
, LVTMATransmitterControl
);
1196 ERROR("%s: BUG: dig setup run on non-dig encoder!\n", __func__
);
1201 ERROR("%s: GetIndexIntoMasterTable failed!\n", __func__
);
1208 if (atom_parse_cmd_header(gAtomContext
, index
, &tableMajor
, &tableMinor
)
1212 // Prepare AtomBIOS arguments
1213 union digTransmitterControl
{
1214 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1
;
1215 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2
;
1216 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3
;
1217 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4
;
1218 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5
;
1220 union digTransmitterControl args
;
1221 memset(&args
, 0, sizeof(args
));
1223 TRACE("%s: table %" B_PRIu8
".%" B_PRIu8
"\n", __func__
,
1224 tableMajor
, tableMinor
);
1226 int connectorObjectID
1227 = (gConnector
[connectorIndex
]->objectID
& OBJECT_ID_MASK
)
1229 uint32 encoderObjectID
= gConnector
[connectorIndex
]->encoder
.objectID
;
1230 uint32 digEncoderID
= encoder_pick_dig(connectorIndex
);
1232 pll_info
* pll
= &gConnector
[connectorIndex
]->encoder
.pll
;
1234 bool isDP
= connector_is_dp(connectorIndex
);
1235 bool linkB
= gConnector
[connectorIndex
]->encoder
.linkEnumeration
1236 == GRAPH_OBJECT_ENUM_ID2
? true : false;
1238 dp_info
* dpInfo
= &gConnector
[connectorIndex
]->dpInfo
;
1241 int dpLaneCount
= 0;
1242 if (dpInfo
->valid
== true) {
1243 dpClock
= dpInfo
->linkRate
;
1244 dpLaneCount
= dpInfo
->laneCount
;
1247 switch (tableMajor
) {
1249 switch (tableMinor
) {
1251 args
.v1
.ucAction
= command
;
1252 if (command
== ATOM_TRANSMITTER_ACTION_INIT
) {
1254 = B_HOST_TO_LENDIAN_INT16(connectorObjectID
);
1256 == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH
) {
1257 args
.v1
.asMode
.ucLaneSel
= laneNumber
;
1258 args
.v1
.asMode
.ucLaneSet
= laneSet
;
1261 args
.v1
.usPixelClock
1262 = B_HOST_TO_LENDIAN_INT16(dpClock
/ 10);
1263 } else if (pixelClock
> 165000) {
1264 args
.v1
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(
1265 (pixelClock
/ 2) / 10);
1267 args
.v1
.usPixelClock
1268 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1272 args
.v1
.ucConfig
= ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL
;
1274 if (digEncoderID
> 0) {
1276 |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER
;
1279 |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER
;
1282 // TODO: IGP DIG Transmitter setup
1284 if ((rdev
->flags
& RADEON_IS_IGP
) && (encoderObjectID
1285 == ENCODER_OBJECT_ID_INTERNAL_UNIPHY
)) {
1286 if (is_dp
|| (radeon_encoder
->pixel_clock
<= 165000)) {
1287 if (igp_lane_info
& 0x1)
1289 |= ATOM_TRANSMITTER_CONFIG_LANE_0_3
;
1290 else if (igp_lane_info
& 0x2)
1292 |= ATOM_TRANSMITTER_CONFIG_LANE_4_7
;
1293 else if (igp_lane_info
& 0x4)
1295 |= ATOM_TRANSMITTER_CONFIG_LANE_8_11
;
1296 else if (igp_lane_info
& 0x8)
1298 |= ATOM_TRANSMITTER_CONFIG_LANE_12_15
;
1300 if (igp_lane_info
& 0x3)
1302 |= ATOM_TRANSMITTER_CONFIG_LANE_0_7
;
1303 else if (igp_lane_info
& 0xc)
1305 |= ATOM_TRANSMITTER_CONFIG_LANE_8_15
;
1311 args
.v1
.ucConfig
|= ATOM_TRANSMITTER_CONFIG_LINKB
;
1313 args
.v1
.ucConfig
|= ATOM_TRANSMITTER_CONFIG_LINKA
;
1316 args
.v1
.ucConfig
|= ATOM_TRANSMITTER_CONFIG_COHERENT
;
1317 else if ((gConnector
[connectorIndex
]->flags
1318 & ATOM_DEVICE_DFP_SUPPORT
) != 0) {
1320 // if coherentMode, i've only ever seen it true
1322 |= ATOM_TRANSMITTER_CONFIG_COHERENT
;
1324 if (pixelClock
> 165000) {
1326 |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK
;
1331 args
.v2
.ucAction
= command
;
1332 if (command
== ATOM_TRANSMITTER_ACTION_INIT
) {
1334 = B_HOST_TO_LENDIAN_INT16(connectorObjectID
);
1336 == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH
) {
1337 args
.v2
.asMode
.ucLaneSel
= laneNumber
;
1338 args
.v2
.asMode
.ucLaneSet
= laneSet
;
1341 args
.v2
.usPixelClock
1342 = B_HOST_TO_LENDIAN_INT16(dpClock
/ 10);
1343 } else if (pixelClock
> 165000) {
1344 args
.v2
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(
1345 (pixelClock
/ 2) / 10);
1347 args
.v2
.usPixelClock
1348 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1351 args
.v2
.acConfig
.ucEncoderSel
= digEncoderID
;
1353 args
.v2
.acConfig
.ucLinkSel
= 1;
1355 switch (encoderObjectID
) {
1356 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1357 args
.v2
.acConfig
.ucTransmitterSel
= 0;
1359 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1360 args
.v2
.acConfig
.ucTransmitterSel
= 1;
1362 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1363 args
.v2
.acConfig
.ucTransmitterSel
= 2;
1368 args
.v2
.acConfig
.fCoherentMode
= 1;
1369 args
.v2
.acConfig
.fDPConnector
= 1;
1370 } else if ((gConnector
[connectorIndex
]->flags
1371 & ATOM_DEVICE_DFP_SUPPORT
) != 0) {
1373 // if coherentMode, i've only ever seen it true
1374 args
.v2
.acConfig
.fCoherentMode
= 1;
1377 if (pixelClock
> 165000)
1378 args
.v2
.acConfig
.fDualLinkConnector
= 1;
1382 args
.v3
.ucAction
= command
;
1383 if (command
== ATOM_TRANSMITTER_ACTION_INIT
) {
1385 = B_HOST_TO_LENDIAN_INT16(connectorObjectID
);
1387 == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH
) {
1388 args
.v3
.asMode
.ucLaneSel
= laneNumber
;
1389 args
.v3
.asMode
.ucLaneSet
= laneSet
;
1392 args
.v3
.usPixelClock
1393 = B_HOST_TO_LENDIAN_INT16(dpClock
/ 10);
1394 } else if (pixelClock
> 165000) {
1395 args
.v3
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(
1396 (pixelClock
/ 2) / 10);
1398 args
.v3
.usPixelClock
1399 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1404 args
.v3
.ucLaneNum
= dpLaneCount
;
1405 else if (pixelClock
> 165000)
1406 args
.v3
.ucLaneNum
= 8;
1408 args
.v3
.ucLaneNum
= 4;
1411 args
.v3
.acConfig
.ucLinkSel
= 1;
1412 if (digEncoderID
& 1)
1413 args
.v3
.acConfig
.ucEncoderSel
= 1;
1415 // Select the PLL for the PHY
1416 // DP PHY to be clocked from external src if possible
1418 // DCE4 has external DCPLL clock for DP
1419 if (isDP
&& gInfo
->dpExternalClock
) {
1420 // use external clock source (id'ed to 2 on DCE4)
1421 args
.v3
.acConfig
.ucRefClkSource
= 2; // EXT clock
1423 args
.v3
.acConfig
.ucRefClkSource
= pll
->id
;
1425 switch (encoderObjectID
) {
1426 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1427 args
.v3
.acConfig
.ucTransmitterSel
= 0;
1429 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1430 args
.v3
.acConfig
.ucTransmitterSel
= 1;
1432 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1433 args
.v3
.acConfig
.ucTransmitterSel
= 2;
1438 args
.v3
.acConfig
.fCoherentMode
= 1;
1439 else if ((gConnector
[connectorIndex
]->flags
1440 & ATOM_DEVICE_DFP_SUPPORT
) != 0) {
1442 // if coherentMode, i've only ever seen it true
1443 args
.v3
.acConfig
.fCoherentMode
= 1;
1445 if (pixelClock
> 165000)
1446 args
.v3
.acConfig
.fDualLinkConnector
= 1;
1450 args
.v4
.ucAction
= command
;
1451 if (command
== ATOM_TRANSMITTER_ACTION_INIT
) {
1453 = B_HOST_TO_LENDIAN_INT16(connectorObjectID
);
1455 == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH
) {
1456 args
.v4
.asMode
.ucLaneSel
= laneNumber
;
1457 args
.v4
.asMode
.ucLaneSet
= laneSet
;
1460 args
.v4
.usPixelClock
1461 = B_HOST_TO_LENDIAN_INT16(dpClock
/ 10);
1462 } else if (pixelClock
> 165000) {
1463 args
.v4
.usPixelClock
= B_HOST_TO_LENDIAN_INT16(
1464 (pixelClock
/ 2) / 10);
1466 args
.v4
.usPixelClock
1467 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1472 args
.v4
.ucLaneNum
= dpLaneCount
;
1473 else if (pixelClock
> 165000)
1474 args
.v4
.ucLaneNum
= 8;
1476 args
.v4
.ucLaneNum
= 4;
1479 args
.v4
.acConfig
.ucLinkSel
= 1;
1480 if (digEncoderID
& 1)
1481 args
.v4
.acConfig
.ucEncoderSel
= 1;
1483 // Select the PLL for the PHY
1484 // DP PHY to be clocked from external src if possible
1485 // DCE5, DCPLL usually generates the DP ref clock
1487 if (gInfo
->dpExternalClock
> 0) {
1488 args
.v4
.acConfig
.ucRefClkSource
1489 = ENCODER_REFCLK_SRC_EXTCLK
;
1491 args
.v4
.acConfig
.ucRefClkSource
1492 = ENCODER_REFCLK_SRC_DCPLL
;
1495 args
.v4
.acConfig
.ucRefClkSource
= pll
->id
;
1497 switch (encoderObjectID
) {
1498 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1499 args
.v4
.acConfig
.ucTransmitterSel
= 0;
1501 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1502 args
.v4
.acConfig
.ucTransmitterSel
= 1;
1504 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1505 args
.v4
.acConfig
.ucTransmitterSel
= 2;
1510 args
.v4
.acConfig
.fCoherentMode
= 1;
1511 else if ((gConnector
[connectorIndex
]->flags
1512 & ATOM_DEVICE_DFP_SUPPORT
) != 0) {
1514 // if coherentMode, i've only ever seen it true
1515 args
.v4
.acConfig
.fCoherentMode
= 1;
1517 if (pixelClock
> 165000)
1518 args
.v4
.acConfig
.fDualLinkConnector
= 1;
1522 args
.v5
.ucAction
= command
;
1526 = B_HOST_TO_LENDIAN_INT16(dpClock
/ 10);
1529 = B_HOST_TO_LENDIAN_INT16(pixelClock
/ 10);
1531 switch (encoderObjectID
) {
1532 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1534 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYB
;
1536 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYA
;
1538 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1540 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYD
;
1542 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYC
;
1544 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1546 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYF
;
1548 args
.v5
.ucPhyId
= ATOM_PHY_ID_UNIPHYE
;
1552 args
.v5
.ucLaneNum
= dpLaneCount
;
1553 } else if (pixelClock
>= 165000) {
1554 args
.v5
.ucLaneNum
= 8;
1556 args
.v5
.ucLaneNum
= 4;
1559 args
.v5
.ucConnObjId
= connectorObjectID
;
1561 = display_get_encoder_mode(connectorIndex
);
1563 if (isDP
&& gInfo
->dpExternalClock
) {
1564 args
.v5
.asConfig
.ucPhyClkSrcId
1565 = ENCODER_REFCLK_SRC_EXTCLK
;
1567 args
.v5
.asConfig
.ucPhyClkSrcId
= pll
->id
;
1571 args
.v5
.asConfig
.ucCoherentMode
= 1;
1572 // DP always coherent
1573 } else if ((gConnector
[connectorIndex
]->flags
1574 & ATOM_DEVICE_DFP_SUPPORT
) != 0) {
1575 // TODO: dig coherent mode? VVV
1576 args
.v5
.asConfig
.ucCoherentMode
= 1;
1579 // RADEON_HPD_NONE? VVV
1580 args
.v5
.asConfig
.ucHPDSel
= 0;
1582 args
.v5
.ucDigEncoderSel
= 1 << digEncoderID
;
1583 args
.v5
.ucDPLaneSet
= laneSet
;
1586 ERROR("%s: unknown table version\n", __func__
);
1590 ERROR("%s: unknown table version\n", __func__
);
1593 return atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1598 encoder_crtc_scratch(uint8 crtcID
)
1600 TRACE("%s\n", __func__
);
1602 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
1603 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1606 uint32 biosScratch3
= Read32(OUT
, R600_SCRATCH_REG3
);
1608 if ((connectorFlags
& ATOM_DEVICE_TV1_SUPPORT
) != 0) {
1609 biosScratch3
&= ~ATOM_S3_TV1_CRTC_ACTIVE
;
1610 biosScratch3
|= (crtcID
<< 18);
1612 if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0) {
1613 biosScratch3
&= ~ATOM_S3_CV_CRTC_ACTIVE
;
1614 biosScratch3
|= (crtcID
<< 24);
1616 if ((connectorFlags
& ATOM_DEVICE_CRT1_SUPPORT
) != 0) {
1617 biosScratch3
&= ~ATOM_S3_CRT1_CRTC_ACTIVE
;
1618 biosScratch3
|= (crtcID
<< 16);
1620 if ((connectorFlags
& ATOM_DEVICE_CRT2_SUPPORT
) != 0) {
1621 biosScratch3
&= ~ATOM_S3_CRT2_CRTC_ACTIVE
;
1622 biosScratch3
|= (crtcID
<< 20);
1624 if ((connectorFlags
& ATOM_DEVICE_LCD1_SUPPORT
) != 0) {
1625 biosScratch3
&= ~ATOM_S3_LCD1_CRTC_ACTIVE
;
1626 biosScratch3
|= (crtcID
<< 17);
1628 if ((connectorFlags
& ATOM_DEVICE_DFP1_SUPPORT
) != 0) {
1629 biosScratch3
&= ~ATOM_S3_DFP1_CRTC_ACTIVE
;
1630 biosScratch3
|= (crtcID
<< 19);
1632 if ((connectorFlags
& ATOM_DEVICE_DFP2_SUPPORT
) != 0) {
1633 biosScratch3
&= ~ATOM_S3_DFP2_CRTC_ACTIVE
;
1634 biosScratch3
|= (crtcID
<< 23);
1636 if ((connectorFlags
& ATOM_DEVICE_DFP3_SUPPORT
) != 0) {
1637 biosScratch3
&= ~ATOM_S3_DFP3_CRTC_ACTIVE
;
1638 biosScratch3
|= (crtcID
<< 25);
1642 Write32(OUT
, R600_SCRATCH_REG3
, biosScratch3
);
1647 encoder_dpms_scratch(uint8 crtcID
, bool power
)
1649 TRACE("%s\n", __func__
);
1651 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
1652 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1655 uint32 biosScratch2
= Read32(OUT
, R600_SCRATCH_REG2
);
1657 if ((connectorFlags
& ATOM_DEVICE_TV1_SUPPORT
) != 0) {
1659 biosScratch2
&= ~ATOM_S2_TV1_DPMS_STATE
;
1661 biosScratch2
|= ATOM_S2_TV1_DPMS_STATE
;
1663 if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0) {
1665 biosScratch2
&= ~ATOM_S2_CV_DPMS_STATE
;
1667 biosScratch2
|= ATOM_S2_CV_DPMS_STATE
;
1669 if ((connectorFlags
& ATOM_DEVICE_CRT1_SUPPORT
) != 0) {
1671 biosScratch2
&= ~ATOM_S2_CRT1_DPMS_STATE
;
1673 biosScratch2
|= ATOM_S2_CRT1_DPMS_STATE
;
1675 if ((connectorFlags
& ATOM_DEVICE_CRT2_SUPPORT
) != 0) {
1677 biosScratch2
&= ~ATOM_S2_CRT2_DPMS_STATE
;
1679 biosScratch2
|= ATOM_S2_CRT2_DPMS_STATE
;
1681 if ((connectorFlags
& ATOM_DEVICE_LCD1_SUPPORT
) != 0) {
1683 biosScratch2
&= ~ATOM_S2_LCD1_DPMS_STATE
;
1685 biosScratch2
|= ATOM_S2_LCD1_DPMS_STATE
;
1687 if ((connectorFlags
& ATOM_DEVICE_DFP1_SUPPORT
) != 0) {
1689 biosScratch2
&= ~ATOM_S2_DFP1_DPMS_STATE
;
1691 biosScratch2
|= ATOM_S2_DFP1_DPMS_STATE
;
1693 if ((connectorFlags
& ATOM_DEVICE_DFP2_SUPPORT
) != 0) {
1695 biosScratch2
&= ~ATOM_S2_DFP2_DPMS_STATE
;
1697 biosScratch2
|= ATOM_S2_DFP2_DPMS_STATE
;
1699 if ((connectorFlags
& ATOM_DEVICE_DFP3_SUPPORT
) != 0) {
1701 biosScratch2
&= ~ATOM_S2_DFP3_DPMS_STATE
;
1703 biosScratch2
|= ATOM_S2_DFP3_DPMS_STATE
;
1705 if ((connectorFlags
& ATOM_DEVICE_DFP4_SUPPORT
) != 0) {
1707 biosScratch2
&= ~ATOM_S2_DFP4_DPMS_STATE
;
1709 biosScratch2
|= ATOM_S2_DFP4_DPMS_STATE
;
1711 if ((connectorFlags
& ATOM_DEVICE_DFP5_SUPPORT
) != 0) {
1713 biosScratch2
&= ~ATOM_S2_DFP5_DPMS_STATE
;
1715 biosScratch2
|= ATOM_S2_DFP5_DPMS_STATE
;
1717 Write32(OUT
, R600_SCRATCH_REG2
, biosScratch2
);
1722 encoder_dpms_set(uint8 crtcID
, int mode
)
1724 TRACE("%s: power: %s\n", __func__
, mode
== B_DPMS_ON
? "true" : "false");
1727 radeon_shared_info
&info
= *gInfo
->shared_info
;
1729 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args
;
1730 memset(&args
, 0, sizeof(args
));
1732 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
1733 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1734 uint16 encoderID
= gConnector
[connectorIndex
]->encoder
.objectID
;
1736 switch (encoderID
) {
1737 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
1738 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
1739 index
= GetIndexIntoMasterTable(COMMAND
, TMDSAOutputControl
);
1741 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
1742 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
1743 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
1744 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
1745 encoder_dpms_set_dig(crtcID
, mode
);
1747 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
1748 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
1749 index
= GetIndexIntoMasterTable(COMMAND
, DVOOutputControl
);
1751 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
1752 if (info
.dceMajor
>= 5)
1753 encoder_dpms_set_dvo(crtcID
, mode
);
1754 else if (info
.dceMajor
>= 3)
1755 encoder_dpms_set_dig(crtcID
, mode
);
1757 index
= GetIndexIntoMasterTable(COMMAND
, DVOOutputControl
);
1759 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
1760 index
= GetIndexIntoMasterTable(COMMAND
, LCD1OutputControl
);
1762 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
1763 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0)
1764 index
= GetIndexIntoMasterTable(COMMAND
, LCD1OutputControl
);
1766 index
= GetIndexIntoMasterTable(COMMAND
, LVTMAOutputControl
);
1768 case ENCODER_OBJECT_ID_INTERNAL_DAC1
:
1769 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
1770 if ((connectorFlags
& ATOM_DEVICE_TV_SUPPORT
) != 0)
1771 index
= GetIndexIntoMasterTable(COMMAND
, TV1OutputControl
);
1772 else if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0)
1773 index
= GetIndexIntoMasterTable(COMMAND
, CV1OutputControl
);
1775 index
= GetIndexIntoMasterTable(COMMAND
, DAC1OutputControl
);
1777 case ENCODER_OBJECT_ID_INTERNAL_DAC2
:
1778 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
1779 if ((connectorFlags
& ATOM_DEVICE_TV_SUPPORT
) != 0)
1780 index
= GetIndexIntoMasterTable(COMMAND
, TV1OutputControl
);
1781 else if ((connectorFlags
& ATOM_DEVICE_CV_SUPPORT
) != 0)
1782 index
= GetIndexIntoMasterTable(COMMAND
, CV1OutputControl
);
1784 index
= GetIndexIntoMasterTable(COMMAND
, DAC2OutputControl
);
1786 // default, none on purpose
1789 // If we have an index, we need to execute a table.
1793 args
.ucAction
= ATOM_ENABLE
;
1795 case B_DPMS_STAND_BY
:
1796 case B_DPMS_SUSPEND
:
1798 args
.ucAction
= ATOM_DISABLE
;
1802 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1803 if (info
.dceMajor
< 5) {
1804 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0) {
1805 args
.ucAction
= args
.ucAction
== ATOM_DISABLE
1806 ? ATOM_LCD_BLOFF
: ATOM_LCD_BLON
;
1807 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1809 encoder_dpms_scratch(crtcID
, true);
1813 // If an external encoder exists, we should flip it on as well
1814 if (gConnector
[connectorIndex
]->encoderExternal
.valid
== true)
1815 encoder_dpms_set_external(crtcID
, mode
);
1820 encoder_dpms_set_dig(uint8 crtcID
, int mode
)
1822 TRACE("%s: power: %s\n", __func__
, mode
== B_DPMS_ON
? "true" : "false");
1824 radeon_shared_info
&info
= *gInfo
->shared_info
;
1825 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
1826 uint32 connectorFlags
= gConnector
[connectorIndex
]->flags
;
1827 pll_info
* pll
= &gConnector
[connectorIndex
]->encoder
.pll
;
1831 if (info
.chipsetID
== RADEON_RV710
1832 || info
.chipsetID
== RADEON_RV730
1833 || (info
.chipsetFlags
& CHIP_APU
) != 0
1834 || info
.dceMajor
>= 5) {
1835 if (info
.dceMajor
>= 6) {
1836 /* We need to call CMD_SETUP before reenabling the encoder,
1837 otherwise we never get a picture */
1838 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1839 ATOM_ENCODER_CMD_SETUP
);
1841 encoder_dig_setup(connectorIndex
, pll
->pixelClock
, ATOM_ENABLE
);
1842 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1843 ATOM_TRANSMITTER_ACTION_SETUP
);
1844 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1845 ATOM_TRANSMITTER_ACTION_ENABLE
);
1846 /* some early dce3.2 boards have a bug in their transmitter
1848 if (info
.chipsetID
!= RADEON_RV710
1849 && info
.chipsetID
!= RADEON_RV730
)
1850 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1851 ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT
);
1853 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1854 ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT
);
1856 if (connector_is_dp(connectorIndex
)) {
1857 if (gConnector
[connectorIndex
]->type
== VIDEO_CONNECTOR_EDP
) {
1858 ERROR("%s: TODO, edp_panel_power for this card!\n",
1860 // atombios_set_edp_panel_power(connector,
1861 // ATOM_TRANSMITTER_ACTION_POWER_ON);
1863 if (info
.dceMajor
>= 4) {
1864 encoder_dig_setup(connectorIndex
, pll
->pixelClock
,
1865 ATOM_ENCODER_CMD_DP_VIDEO_OFF
);
1868 dp_link_train(crtcID
);
1869 if (info
.dceMajor
>= 4) {
1870 encoder_dig_setup(connectorIndex
, pll
->pixelClock
,
1871 ATOM_ENCODER_CMD_DP_VIDEO_ON
);
1873 // not sure what AtomBIOS table/command sets this
1874 // register, but it's required to get the video output
1875 Write32(OUT
, AVIVO_DP_VID_STREAM_CNTL
, 0x201);
1877 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0) {
1878 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
,
1879 0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLON
);
1882 case B_DPMS_STAND_BY
:
1883 case B_DPMS_SUSPEND
:
1885 if ((info
.chipsetFlags
& CHIP_APU
) != 0 || info
.dceMajor
>= 5) {
1886 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1887 ATOM_TRANSMITTER_ACTION_DISABLE
);
1889 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1890 ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT
);
1891 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
, 0, 0,
1892 ATOM_TRANSMITTER_ACTION_DISABLE
);
1893 encoder_dig_setup(connectorIndex
, pll
->pixelClock
, ATOM_DISABLE
);
1895 if (connector_is_dp(connectorIndex
)) {
1896 if (info
.dceMajor
>= 4) {
1897 encoder_dig_setup(connectorIndex
, pll
->pixelClock
,
1898 ATOM_ENCODER_CMD_DP_VIDEO_OFF
);
1900 if (connector
->connector_type
== DRM_MODE_CONNECTOR_eDP
) {
1901 atombios_set_edp_panel_power(connector
,
1902 ATOM_TRANSMITTER_ACTION_POWER_OFF
);
1903 radeon_dig_connector
->edp_on
= false;
1907 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0) {
1908 transmitter_dig_setup(connectorIndex
, pll
->pixelClock
,
1909 0, 0, ATOM_TRANSMITTER_ACTION_LCD_BLOFF
);
1917 encoder_dpms_set_external(uint8 crtcID
, int mode
)
1919 TRACE("%s: power: %s\n", __func__
, mode
== B_DPMS_ON
? "true" : "false");
1921 radeon_shared_info
&info
= *gInfo
->shared_info
;
1922 uint32 connectorIndex
= gDisplay
[crtcID
]->connectorIndex
;
1926 if ((info
.chipsetFlags
& CHIP_APU
) != 0) {
1927 encoder_external_setup(connectorIndex
,
1928 EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT
);
1929 encoder_external_setup(connectorIndex
,
1930 EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF
);
1932 encoder_external_setup(connectorIndex
, ATOM_ENABLE
);
1935 case B_DPMS_STAND_BY
:
1936 case B_DPMS_SUSPEND
:
1938 if ((info
.chipsetFlags
& CHIP_APU
) != 0) {
1939 encoder_external_setup(connectorIndex
,
1940 EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING
);
1941 encoder_external_setup(connectorIndex
,
1942 EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT
);
1944 encoder_external_setup(connectorIndex
, ATOM_DISABLE
);
1952 encoder_dpms_set_dvo(uint8 crtcID
, int mode
)
1954 ERROR("%s: TODO, dvo encoder dpms stub\n", __func__
);
1959 encoder_output_lock(bool lock
)
1961 TRACE("%s: %s\n", __func__
, lock
? "true" : "false");
1962 uint32 biosScratch6
= Read32(OUT
, R600_SCRATCH_REG6
);
1965 biosScratch6
|= ATOM_S6_CRITICAL_STATE
;
1966 biosScratch6
&= ~ATOM_S6_ACC_MODE
;
1968 biosScratch6
&= ~ATOM_S6_CRITICAL_STATE
;
1969 biosScratch6
|= ATOM_S6_ACC_MODE
;
1972 Write32(OUT
, R600_SCRATCH_REG6
, biosScratch6
);
1975 static const char* encoder_name_matrix
[] = {
1977 "Internal Radeon LVDS",
1978 "Internal Radeon TMDS1",
1979 "Internal Radeon TMDS2",
1980 "Internal Radeon DAC1",
1981 "Internal Radeon DAC2 (TV)",
1982 "Internal Radeon SDVOA",
1983 "Internal Radeon SDVOB",
1984 "External 3rd party SI170B",
1985 "External 3rd party CH7303",
1986 "External 3rd party CH7301",
1987 "Internal Radeon DVO1",
1988 "External 3rd party SDVOA",
1989 "External 3rd party SDVOB",
1990 "External 3rd party TITFP513",
1992 "External 3rd party VT1623",
1993 "External HDMI SI1930",
1995 "Internal Kaleidoscope TMDS1",
1996 "Internal Kaleidoscope DVO1",
1997 "Internal Kaleidoscope DAC1",
1998 "Internal Kaleidoscope DAC2",
1999 "External Kaleidoscope SI178",
2001 "Internal Kaleidoscope DDI",
2002 "External Kaleidoscope VT1625",
2003 "External Kaleidoscope HDMI SI1932",
2004 "External Kaleidoscope DP AN9801",
2005 "External Kaleidoscope DP DP501",
2006 "Internal Kaleidoscope UNIPHY",
2007 "Internal Kaleidoscope LVTMA",
2008 "Internal Kaleidoscope UNIPHY1",
2009 "Internal Kaleidoscope UNIPHY2",
2010 "External Nutmeg Bridge",
2011 "External Travis Bridge",
2012 "Internal Kaleidoscope VCE"
2017 encoder_name_lookup(uint32 encoderID
) {
2018 if (encoderID
< B_COUNT_OF(encoder_name_matrix
))
2019 return encoder_name_matrix
[encoderID
];
2026 encoder_object_lookup(uint32 connectorFlags
, uint8 dacID
)
2028 // used on older cards to take a guess at the encoder
2031 radeon_shared_info
&info
= *gInfo
->shared_info
;
2035 switch (connectorFlags
) {
2036 case ATOM_DEVICE_CRT1_SUPPORT
:
2037 case ATOM_DEVICE_TV1_SUPPORT
:
2038 case ATOM_DEVICE_TV2_SUPPORT
:
2039 case ATOM_DEVICE_CRT2_SUPPORT
:
2040 case ATOM_DEVICE_CV_SUPPORT
:
2043 if ((info
.chipsetID
== RADEON_RS400
)
2044 || (info
.chipsetID
== RADEON_RS480
))
2045 ret
= ENCODER_INTERNAL_DAC2_ENUM_ID1
;
2046 else if (info
.chipsetID
>= RADEON_RS600
)
2047 ret
= ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1
;
2049 ret
= ENCODER_INTERNAL_DAC1_ENUM_ID1
;
2052 if (info
.chipsetID
>= RADEON_RS600
)
2053 ret
= ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1
;
2055 ret
= ENCODER_INTERNAL_DAC2_ENUM_ID1
;
2058 case 3: // external dac
2059 if (info
.chipsetID
>= RADEON_RS600
)
2060 ret
= ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1
;
2062 ret
= ENCODER_INTERNAL_DVO1_ENUM_ID1
;
2066 case ATOM_DEVICE_LCD1_SUPPORT
:
2067 if (info
.chipsetID
>= RADEON_RS600
)
2068 ret
= ENCODER_INTERNAL_LVTM1_ENUM_ID1
;
2070 ret
= ENCODER_INTERNAL_LVDS_ENUM_ID1
;
2072 case ATOM_DEVICE_DFP1_SUPPORT
:
2073 if ((info
.chipsetID
== RADEON_RS400
)
2074 || (info
.chipsetID
== RADEON_RS480
))
2075 ret
= ENCODER_INTERNAL_DVO1_ENUM_ID1
;
2076 else if (info
.chipsetID
>= RADEON_RS600
)
2077 ret
= ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1
;
2079 ret
= ENCODER_INTERNAL_TMDS1_ENUM_ID1
;
2081 case ATOM_DEVICE_LCD2_SUPPORT
:
2082 case ATOM_DEVICE_DFP2_SUPPORT
:
2083 if ((info
.chipsetID
== RADEON_RS600
)
2084 || (info
.chipsetID
== RADEON_RS690
)
2085 || (info
.chipsetID
== RADEON_RS740
))
2086 ret
= ENCODER_INTERNAL_DDI_ENUM_ID1
;
2087 else if (info
.chipsetID
>= RADEON_RS600
)
2088 ret
= ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1
;
2090 ret
= ENCODER_INTERNAL_DVO1_ENUM_ID1
;
2092 case ATOM_DEVICE_DFP3_SUPPORT
:
2093 ret
= ENCODER_INTERNAL_LVTM1_ENUM_ID1
;
2102 encoder_type_lookup(uint32 encoderID
, uint32 connectorFlags
)
2104 switch (encoderID
) {
2105 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
2106 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
2107 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
2108 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
2109 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0)
2110 return VIDEO_ENCODER_LVDS
;
2112 return VIDEO_ENCODER_TMDS
;
2114 case ENCODER_OBJECT_ID_INTERNAL_DAC1
:
2115 return VIDEO_ENCODER_DAC
;
2116 case ENCODER_OBJECT_ID_INTERNAL_DAC2
:
2117 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1
:
2118 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2
:
2119 return VIDEO_ENCODER_TVDAC
;
2120 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
2121 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
2122 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
2123 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
2124 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
2125 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
2126 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
2127 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0)
2128 return VIDEO_ENCODER_LVDS
;
2129 else if ((connectorFlags
& ATOM_DEVICE_CRT_SUPPORT
) != 0)
2130 return VIDEO_ENCODER_DAC
;
2132 return VIDEO_ENCODER_TMDS
;
2134 case ENCODER_OBJECT_ID_SI170B
:
2135 case ENCODER_OBJECT_ID_CH7303
:
2136 case ENCODER_OBJECT_ID_EXTERNAL_SDVOA
:
2137 case ENCODER_OBJECT_ID_EXTERNAL_SDVOB
:
2138 case ENCODER_OBJECT_ID_TITFP513
:
2139 case ENCODER_OBJECT_ID_VT1623
:
2140 case ENCODER_OBJECT_ID_HDMI_SI1930
:
2141 case ENCODER_OBJECT_ID_TRAVIS
:
2142 case ENCODER_OBJECT_ID_NUTMEG
:
2143 if ((connectorFlags
& ATOM_DEVICE_LCD_SUPPORT
) != 0)
2144 return VIDEO_ENCODER_LVDS
;
2145 else if ((connectorFlags
& ATOM_DEVICE_CRT_SUPPORT
) != 0)
2146 return VIDEO_ENCODER_DAC
;
2148 return VIDEO_ENCODER_TMDS
;
2152 return VIDEO_ENCODER_NONE
;
2157 encoder_is_external(uint32 encoderID
)
2159 switch (encoderID
) {
2160 case ENCODER_OBJECT_ID_SI170B
:
2161 case ENCODER_OBJECT_ID_CH7303
:
2162 case ENCODER_OBJECT_ID_EXTERNAL_SDVOA
:
2163 case ENCODER_OBJECT_ID_EXTERNAL_SDVOB
:
2164 case ENCODER_OBJECT_ID_TITFP513
:
2165 case ENCODER_OBJECT_ID_VT1623
:
2166 case ENCODER_OBJECT_ID_HDMI_SI1930
:
2167 case ENCODER_OBJECT_ID_TRAVIS
:
2168 case ENCODER_OBJECT_ID_NUTMEG
:
2177 encoder_is_dp_bridge(uint32 encoderID
)
2179 switch (encoderID
) {
2180 case ENCODER_OBJECT_ID_TRAVIS
:
2181 case ENCODER_OBJECT_ID_NUTMEG
: