2 * Copyright 2006-2013, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Alexander von Gluck, kallisti5@unixzen.com
7 * Bill Randle, billr@neocat.org
11 * It's dangerous to go alone, take this!
12 * framebuffer -> crtc -> encoder -> transmitter -> connector -> monitor
21 #include "accelerant.h"
22 #include "accelerant_protos.h"
24 #include "connector.h"
25 #include "displayport.h"
31 extern "C" void _sPrintf(const char* format
, ...);
32 # define TRACE(x...) _sPrintf("radeon_hd: " x)
34 # define TRACE(x...) ;
37 #define ERROR(x...) _sPrintf("radeon_hd: " x)
40 /*! Populate regs with device dependant register locations */
42 init_registers(register_info
* regs
, uint8 crtcID
)
44 memset(regs
, 0, sizeof(register_info
));
46 radeon_shared_info
&info
= *gInfo
->shared_info
;
48 if (info
.chipsetID
>= RADEON_CEDAR
) {
54 offset
= EVERGREEN_CRTC0_REGISTER_OFFSET
;
55 regs
->vgaControl
= AVIVO_D1VGA_CONTROL
;
58 offset
= EVERGREEN_CRTC1_REGISTER_OFFSET
;
59 regs
->vgaControl
= AVIVO_D2VGA_CONTROL
;
62 offset
= EVERGREEN_CRTC2_REGISTER_OFFSET
;
63 regs
->vgaControl
= EVERGREEN_D3VGA_CONTROL
;
66 offset
= EVERGREEN_CRTC3_REGISTER_OFFSET
;
67 regs
->vgaControl
= EVERGREEN_D4VGA_CONTROL
;
70 offset
= EVERGREEN_CRTC4_REGISTER_OFFSET
;
71 regs
->vgaControl
= EVERGREEN_D5VGA_CONTROL
;
74 offset
= EVERGREEN_CRTC5_REGISTER_OFFSET
;
75 regs
->vgaControl
= EVERGREEN_D6VGA_CONTROL
;
78 ERROR("%s: Unknown CRTC %" B_PRIu32
"\n",
83 regs
->crtcOffset
= offset
;
85 regs
->grphEnable
= EVERGREEN_GRPH_ENABLE
+ offset
;
86 regs
->grphControl
= EVERGREEN_GRPH_CONTROL
+ offset
;
87 regs
->grphSwapControl
= EVERGREEN_GRPH_SWAP_CONTROL
+ offset
;
89 regs
->grphPrimarySurfaceAddr
90 = EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS
+ offset
;
91 regs
->grphSecondarySurfaceAddr
92 = EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS
+ offset
;
93 regs
->grphPrimarySurfaceAddrHigh
94 = EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH
+ offset
;
95 regs
->grphSecondarySurfaceAddrHigh
96 = EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH
+ offset
;
98 regs
->grphPitch
= EVERGREEN_GRPH_PITCH
+ offset
;
99 regs
->grphSurfaceOffsetX
100 = EVERGREEN_GRPH_SURFACE_OFFSET_X
+ offset
;
101 regs
->grphSurfaceOffsetY
102 = EVERGREEN_GRPH_SURFACE_OFFSET_Y
+ offset
;
103 regs
->grphXStart
= EVERGREEN_GRPH_X_START
+ offset
;
104 regs
->grphYStart
= EVERGREEN_GRPH_Y_START
+ offset
;
105 regs
->grphXEnd
= EVERGREEN_GRPH_X_END
+ offset
;
106 regs
->grphYEnd
= EVERGREEN_GRPH_Y_END
+ offset
;
107 regs
->modeDesktopHeight
= EVERGREEN_DESKTOP_HEIGHT
+ offset
;
108 regs
->modeDataFormat
= EVERGREEN_DATA_FORMAT
+ offset
;
109 regs
->viewportStart
= EVERGREEN_VIEWPORT_START
+ offset
;
110 regs
->viewportSize
= EVERGREEN_VIEWPORT_SIZE
+ offset
;
112 } else if (info
.chipsetID
>= RADEON_RV770
) {
118 offset
= R700_CRTC0_REGISTER_OFFSET
;
119 regs
->vgaControl
= AVIVO_D1VGA_CONTROL
;
120 regs
->grphPrimarySurfaceAddrHigh
121 = R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH
;
124 offset
= R700_CRTC1_REGISTER_OFFSET
;
125 regs
->vgaControl
= AVIVO_D2VGA_CONTROL
;
126 regs
->grphPrimarySurfaceAddrHigh
127 = R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH
;
130 ERROR("%s: Unknown CRTC %" B_PRIu32
"\n",
135 regs
->crtcOffset
= offset
;
137 regs
->grphEnable
= AVIVO_D1GRPH_ENABLE
+ offset
;
138 regs
->grphControl
= AVIVO_D1GRPH_CONTROL
+ offset
;
139 regs
->grphSwapControl
= AVIVO_D1GRPH_SWAP_CNTL
+ offset
;
141 regs
->grphPrimarySurfaceAddr
142 = R700_D1GRPH_PRIMARY_SURFACE_ADDRESS
+ offset
;
143 regs
->grphSecondarySurfaceAddr
144 = R700_D1GRPH_SECONDARY_SURFACE_ADDRESS
+ offset
;
146 regs
->grphPitch
= AVIVO_D1GRPH_PITCH
+ offset
;
147 regs
->grphSurfaceOffsetX
= AVIVO_D1GRPH_SURFACE_OFFSET_X
+ offset
;
148 regs
->grphSurfaceOffsetY
= AVIVO_D1GRPH_SURFACE_OFFSET_Y
+ offset
;
149 regs
->grphXStart
= AVIVO_D1GRPH_X_START
+ offset
;
150 regs
->grphYStart
= AVIVO_D1GRPH_Y_START
+ offset
;
151 regs
->grphXEnd
= AVIVO_D1GRPH_X_END
+ offset
;
152 regs
->grphYEnd
= AVIVO_D1GRPH_Y_END
+ offset
;
154 regs
->modeDesktopHeight
= AVIVO_D1MODE_DESKTOP_HEIGHT
+ offset
;
155 regs
->modeDataFormat
= AVIVO_D1MODE_DATA_FORMAT
+ offset
;
156 regs
->viewportStart
= AVIVO_D1MODE_VIEWPORT_START
+ offset
;
157 regs
->viewportSize
= AVIVO_D1MODE_VIEWPORT_SIZE
+ offset
;
159 } else if (info
.chipsetID
>= RADEON_RS600
) {
165 offset
= R600_CRTC0_REGISTER_OFFSET
;
166 regs
->vgaControl
= AVIVO_D1VGA_CONTROL
;
169 offset
= R600_CRTC1_REGISTER_OFFSET
;
170 regs
->vgaControl
= AVIVO_D2VGA_CONTROL
;
173 ERROR("%s: Unknown CRTC %" B_PRIu32
"\n",
178 regs
->crtcOffset
= offset
;
180 regs
->grphEnable
= AVIVO_D1GRPH_ENABLE
+ offset
;
181 regs
->grphControl
= AVIVO_D1GRPH_CONTROL
+ offset
;
182 regs
->grphSwapControl
= AVIVO_D1GRPH_SWAP_CNTL
+ offset
;
184 regs
->grphPrimarySurfaceAddr
185 = AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS
+ offset
;
186 regs
->grphSecondarySurfaceAddr
187 = AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS
+ offset
;
189 // Surface Address high only used on r700 and higher
190 regs
->grphPrimarySurfaceAddrHigh
= 0xDEAD;
191 regs
->grphSecondarySurfaceAddrHigh
= 0xDEAD;
193 regs
->grphPitch
= AVIVO_D1GRPH_PITCH
+ offset
;
194 regs
->grphSurfaceOffsetX
= AVIVO_D1GRPH_SURFACE_OFFSET_X
+ offset
;
195 regs
->grphSurfaceOffsetY
= AVIVO_D1GRPH_SURFACE_OFFSET_Y
+ offset
;
196 regs
->grphXStart
= AVIVO_D1GRPH_X_START
+ offset
;
197 regs
->grphYStart
= AVIVO_D1GRPH_Y_START
+ offset
;
198 regs
->grphXEnd
= AVIVO_D1GRPH_X_END
+ offset
;
199 regs
->grphYEnd
= AVIVO_D1GRPH_Y_END
+ offset
;
201 regs
->modeDesktopHeight
= AVIVO_D1MODE_DESKTOP_HEIGHT
+ offset
;
202 regs
->modeDataFormat
= AVIVO_D1MODE_DATA_FORMAT
+ offset
;
203 regs
->viewportStart
= AVIVO_D1MODE_VIEWPORT_START
+ offset
;
204 regs
->viewportSize
= AVIVO_D1MODE_VIEWPORT_SIZE
+ offset
;
206 // this really shouldn't happen unless a driver PCIID chipset is wrong
207 TRACE("%s, unknown Radeon chipset: %s\n", __func__
,
212 TRACE("%s, registers for ATI chipset %s crt #%d loaded\n", __func__
,
213 info
.chipsetName
, crtcID
);
220 detect_crt_ranges(uint32 crtid
)
222 edid1_info
* edid
= &gDisplay
[crtid
]->edidData
;
224 // Scan each display EDID description for monitor ranges
225 for (uint32 index
= 0; index
< EDID1_NUM_DETAILED_MONITOR_DESC
; index
++) {
227 edid1_detailed_monitor
* monitor
228 = &edid
->detailed_monitor
[index
];
230 if (monitor
->monitor_desc_type
== EDID1_MONITOR_RANGES
) {
231 edid1_monitor_range range
= monitor
->data
.monitor_range
;
232 gDisplay
[crtid
]->vfreqMin
= range
.min_v
; /* in Hz */
233 gDisplay
[crtid
]->vfreqMax
= range
.max_v
;
234 gDisplay
[crtid
]->hfreqMin
= range
.min_h
; /* in kHz */
235 gDisplay
[crtid
]->hfreqMax
= range
.max_h
;
247 // reset known displays
248 for (uint32 id
= 0; id
< MAX_DISPLAY
; id
++) {
249 gDisplay
[id
]->attached
= false;
250 gDisplay
[id
]->powered
= false;
251 gDisplay
[id
]->foundRanges
= false;
254 uint32 displayIndex
= 0;
255 for (uint32 id
= 0; id
< ATOM_MAX_SUPPORTED_DEVICE
; id
++) {
256 if (gConnector
[id
]->valid
== false)
258 if (displayIndex
>= MAX_DISPLAY
)
261 if (gConnector
[id
]->type
== VIDEO_CONNECTOR_9DIN
) {
262 TRACE("%s: connector(%" B_PRIu32
"): Skipping 9DIN connector "
263 "(not yet supported)\n", __func__
, id
);
267 if (gConnector
[id
]->type
== VIDEO_CONNECTOR_DP
) {
268 TRACE("%s: connector(%" B_PRIu32
"): Checking DP.\n", __func__
, id
);
270 if (gConnector
[id
]->encoderExternal
.valid
== true) {
271 // If this has a valid external encoder (dp bridge)
272 // normally TRAVIS (LVDS) or NUTMEG (VGA)
273 TRACE("%s: external encoder, performing bridge DDC setup\n",
275 encoder_external_setup(id
,
276 EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP
);
278 edid1_info
* edid
= &gDisplay
[displayIndex
]->edidData
;
279 gDisplay
[displayIndex
]->attached
280 = ddc2_dp_read_edid1(id
, edid
);
282 // TODO: DDC Router switching for DisplayPort (and others?)
284 if (gDisplay
[displayIndex
]->attached
) {
285 TRACE("%s: connector(%" B_PRIu32
"): Found DisplayPort EDID!\n",
291 if (gConnector
[id
]->type
== VIDEO_CONNECTOR_LVDS
) {
292 display_mode preferredMode
;
293 bool lvdsInfoFound
= connector_read_mode_lvds(id
,
295 TRACE("%s: connector(%" B_PRIu32
"): bit-banging LVDS for EDID.\n",
298 gDisplay
[displayIndex
]->attached
= connector_read_edid(id
,
299 &gDisplay
[displayIndex
]->edidData
);
301 if (!gDisplay
[displayIndex
]->attached
&& lvdsInfoFound
) {
302 // If we didn't find ddc edid data, fallback to lvdsInfo
303 // We have to call connector_read_mode_lvds first to
304 // collect SS data for the lvds connector
305 TRACE("%s: connector(%" B_PRIu32
"): using AtomBIOS LVDS_Info "
306 "preferred mode\n", __func__
, id
);
307 gDisplay
[displayIndex
]->attached
= true;
308 memcpy(&gDisplay
[displayIndex
]->preferredMode
,
309 &preferredMode
, sizeof(display_mode
));
313 // If no display found yet, try more standard detection methods
314 if (gDisplay
[displayIndex
]->attached
== false) {
315 TRACE("%s: connector(%" B_PRIu32
"): bit-banging ddc for EDID.\n",
318 // Bit-bang edid from connector
319 gDisplay
[displayIndex
]->attached
= connector_read_edid(id
,
320 &gDisplay
[displayIndex
]->edidData
);
323 if (gDisplay
[displayIndex
]->attached
) {
324 TRACE("%s: connector(%" B_PRIu32
"): found EDID data.\n",
327 if (gConnector
[id
]->type
== VIDEO_CONNECTOR_DVII
328 || gConnector
[id
]->type
== VIDEO_CONNECTOR_HDMIB
) {
329 // These connectors can share gpio pins for data
330 // communication between digital and analog encoders
331 // (DVI-I is most common)
332 edid1_info
* edid
= &gDisplay
[displayIndex
]->edidData
;
335 = gConnector
[id
]->encoder
.type
== VIDEO_ENCODER_TVDAC
336 || gConnector
[id
]->encoder
.type
== VIDEO_ENCODER_DAC
;
338 = gConnector
[id
]->encoder
.type
== VIDEO_ENCODER_TMDS
;
340 bool digitalEdid
= edid
->display
.input_type
? true : false;
342 if (digitalEdid
&& analogEncoder
) {
343 // Digital EDID + analog encoder? Lets try a load test
344 gDisplay
[displayIndex
]->attached
345 = encoder_analog_load_detect(id
);
346 } else if (!digitalEdid
&& digitalEncoder
) {
347 // non-digital EDID + digital encoder? Nope.
348 gDisplay
[displayIndex
]->attached
= false;
351 // Else... everything aligns as it should and attached = 1
356 if (gDisplay
[displayIndex
]->attached
!= true) {
357 // Nothing interesting here, move along
361 // We found a valid / attached display
363 gDisplay
[displayIndex
]->connectorIndex
= id
;
364 // Populate physical connector index from gConnector
366 init_registers(gDisplay
[displayIndex
]->regs
, displayIndex
);
368 if (gDisplay
[displayIndex
]->preferredMode
.virtual_width
> 0) {
369 // Found a single preferred mode
370 gDisplay
[displayIndex
]->foundRanges
= false;
372 // Use edid data and pull ranges
373 if (detect_crt_ranges(displayIndex
) == B_OK
)
374 gDisplay
[displayIndex
]->foundRanges
= true;
380 // fallback if no attached monitors were found
381 if (displayIndex
== 0) {
382 // This is a hack, however as we don't support HPD just yet,
383 // it tries to prevent a "no displays" situation.
384 ERROR("%s: ERROR: 0 attached monitors were found on display connectors."
385 " Injecting first connector as a last resort.\n", __func__
);
386 for (uint32 id
= 0; id
< ATOM_MAX_SUPPORTED_DEVICE
; id
++) {
387 // skip TV DAC connectors as likely fallback isn't for TV
388 if (gConnector
[id
]->encoder
.type
== VIDEO_ENCODER_TVDAC
)
390 gDisplay
[0]->attached
= true;
391 gDisplay
[0]->connectorIndex
= id
;
392 init_registers(gDisplay
[0]->regs
, 0);
393 if (detect_crt_ranges(0) == B_OK
)
394 gDisplay
[0]->foundRanges
= true;
399 // Initial boot state is the first two crtc's powered
400 if (gDisplay
[0]->attached
== true)
401 gDisplay
[0]->powered
= true;
402 if (gDisplay
[1]->attached
== true)
403 gDisplay
[1]->powered
= true;
412 TRACE("Currently detected monitors===============\n");
413 for (uint32 id
= 0; id
< MAX_DISPLAY
; id
++) {
414 ERROR("Display #%" B_PRIu32
" attached = %s\n",
415 id
, gDisplay
[id
]->attached
? "true" : "false");
417 uint32 connectorIndex
= gDisplay
[id
]->connectorIndex
;
419 if (gDisplay
[id
]->attached
) {
420 uint32 connectorType
= gConnector
[connectorIndex
]->type
;
421 uint32 encoderType
= gConnector
[connectorIndex
]->encoder
.type
;
422 ERROR(" + connector ID: %" B_PRIu32
"\n", connectorIndex
);
423 ERROR(" + connector type: %s\n", get_connector_name(connectorType
));
424 ERROR(" + encoder type: %s\n", get_encoder_name(encoderType
));
425 ERROR(" + limits: Vert Min/Max: %" B_PRIu32
"/%" B_PRIu32
"\n",
426 gDisplay
[id
]->vfreqMin
, gDisplay
[id
]->vfreqMax
);
427 ERROR(" + limits: Horz Min/Max: %" B_PRIu32
"/%" B_PRIu32
"\n",
428 gDisplay
[id
]->hfreqMin
, gDisplay
[id
]->hfreqMax
);
431 TRACE("==========================================\n");
436 display_get_encoder_mode(uint32 connectorIndex
)
438 // Is external DisplayPort Bridge?
439 if (gConnector
[connectorIndex
]->encoderExternal
.valid
== true
440 && gConnector
[connectorIndex
]->encoderExternal
.isDPBridge
== true) {
441 return ATOM_ENCODER_MODE_DP
;
444 // DVO Encoders (should be bridges)
445 switch (gConnector
[connectorIndex
]->encoder
.objectID
) {
446 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
447 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
448 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
449 return ATOM_ENCODER_MODE_DVO
;
452 // Find crtc for connector so we can identify source of edid data
454 for (int32 id
= 0; id
< MAX_DISPLAY
; id
++) {
455 if (gDisplay
[id
]->connectorIndex
== connectorIndex
) {
460 bool edidDigital
= false;
462 ERROR("%s: BUG: executed on connector without crtc!\n", __func__
);
464 edid1_info
* edid
= &gDisplay
[crtc
]->edidData
;
465 edidDigital
= edid
->display
.input_type
? true : false;
468 // Normal encoder situations
469 switch (gConnector
[connectorIndex
]->type
) {
470 case VIDEO_CONNECTOR_DVII
:
471 case VIDEO_CONNECTOR_HDMIB
: /* HDMI-B is DL-DVI; analog works fine */
472 // TODO: if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
473 // if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
475 return ATOM_ENCODER_MODE_DVI
;
477 return ATOM_ENCODER_MODE_CRT
;
479 case VIDEO_CONNECTOR_DVID
:
480 case VIDEO_CONNECTOR_HDMIA
:
482 // TODO: if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
483 // if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
484 return ATOM_ENCODER_MODE_DVI
;
485 case VIDEO_CONNECTOR_LVDS
:
486 return ATOM_ENCODER_MODE_LVDS
;
487 case VIDEO_CONNECTOR_DP
:
488 // dig_connector = radeon_connector->con_priv;
489 // if ((dig_connector->dp_sink_type
490 // == CONNECTOR_OBJECT_ID_DISPLAYPORT)
491 // || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
492 // return ATOM_ENCODER_MODE_DP;
494 // TODO: if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
495 // if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
496 return ATOM_ENCODER_MODE_DP
;
497 case VIDEO_CONNECTOR_EDP
:
498 return ATOM_ENCODER_MODE_DP
;
499 case VIDEO_CONNECTOR_DVIA
:
500 case VIDEO_CONNECTOR_VGA
:
501 return ATOM_ENCODER_MODE_CRT
;
502 case VIDEO_CONNECTOR_COMPOSITE
:
503 case VIDEO_CONNECTOR_SVIDEO
:
504 case VIDEO_CONNECTOR_9DIN
:
505 return ATOM_ENCODER_MODE_TV
;
511 display_crtc_lock(uint8 crtcID
, int command
)
513 TRACE("%s\n", __func__
);
515 ENABLE_CRTC_PS_ALLOCATION args
;
517 = GetIndexIntoMasterTable(COMMAND
, UpdateCRTC_DoubleBufferRegisters
);
519 memset(&args
, 0, sizeof(args
));
521 args
.ucCRTC
= crtcID
;
522 args
.ucEnable
= command
;
524 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
529 display_crtc_blank(uint8 crtcID
, int command
)
531 TRACE("%s\n", __func__
);
533 BLANK_CRTC_PS_ALLOCATION args
;
534 int index
= GetIndexIntoMasterTable(COMMAND
, BlankCRTC
);
536 memset(&args
, 0, sizeof(args
));
538 args
.ucCRTC
= crtcID
;
539 args
.ucBlanking
= command
;
541 args
.usBlackColorRCr
= 0;
542 args
.usBlackColorGY
= 0;
543 args
.usBlackColorBCb
= 0;
545 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
550 display_crtc_scale(uint8 crtcID
, display_mode
* mode
)
552 TRACE("%s\n", __func__
);
553 ENABLE_SCALER_PS_ALLOCATION args
;
554 int index
= GetIndexIntoMasterTable(COMMAND
, EnableScaler
);
556 memset(&args
, 0, sizeof(args
));
558 args
.ucScaler
= crtcID
;
559 args
.ucEnable
= ATOM_SCALER_DISABLE
;
561 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
566 display_crtc_dpms(uint8 crtcID
, int mode
)
568 radeon_shared_info
&info
= *gInfo
->shared_info
;
572 TRACE("%s: crtc %" B_PRIu8
" dpms powerup\n", __func__
, crtcID
);
573 if (gDisplay
[crtcID
]->attached
== false)
575 display_crtc_power(crtcID
, ATOM_ENABLE
);
576 gDisplay
[crtcID
]->powered
= true;
577 if (info
.dceMajor
>= 3 && info
.dceMajor
< 6)
578 display_crtc_memreq(crtcID
, ATOM_ENABLE
);
579 display_crtc_blank(crtcID
, ATOM_BLANKING_OFF
);
581 case B_DPMS_STAND_BY
:
584 TRACE("%s: crtc %" B_PRIu8
" dpms powerdown\n", __func__
, crtcID
);
585 if (gDisplay
[crtcID
]->attached
== false)
587 if (gDisplay
[crtcID
]->powered
== true)
588 display_crtc_blank(crtcID
, ATOM_BLANKING
);
589 if (info
.dceMajor
>= 3 && info
.dceMajor
< 6)
590 display_crtc_memreq(crtcID
, ATOM_DISABLE
);
591 display_crtc_power(crtcID
, ATOM_DISABLE
);
592 gDisplay
[crtcID
]->powered
= false;
598 display_dce45_crtc_load_lut(uint8 crtcID
)
600 radeon_shared_info
&info
= *gInfo
->shared_info
;
601 register_info
* regs
= gDisplay
[crtcID
]->regs
;
603 TRACE("%s: crtcID %" B_PRIu8
"\n", __func__
, crtcID
);
605 uint16
* r
= info
.color_data
;
609 if (info
.dceMajor
>= 5) {
610 Write32(OUT
, NI_INPUT_CSC_CONTROL
+ regs
->crtcOffset
,
611 NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS
)
612 | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS
));
613 Write32(OUT
, NI_PRESCALE_GRPH_CONTROL
+ regs
->crtcOffset
,
614 NI_GRPH_PRESCALE_BYPASS
);
615 Write32(OUT
, NI_PRESCALE_OVL_CONTROL
+ regs
->crtcOffset
,
616 NI_OVL_PRESCALE_BYPASS
);
617 Write32(OUT
, NI_INPUT_GAMMA_CONTROL
+ regs
->crtcOffset
,
618 NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT
) |
619 NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT
));
622 Write32(OUT
, EVERGREEN_DC_LUT_CONTROL
+ regs
->crtcOffset
, 0);
624 Write32(OUT
, EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE
+ regs
->crtcOffset
, 0);
625 Write32(OUT
, EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN
+ regs
->crtcOffset
, 0);
626 Write32(OUT
, EVERGREEN_DC_LUT_BLACK_OFFSET_RED
+ regs
->crtcOffset
, 0);
628 Write32(OUT
, EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE
+ regs
->crtcOffset
, 0xffff);
629 Write32(OUT
, EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN
+ regs
->crtcOffset
, 0xffff);
630 Write32(OUT
, EVERGREEN_DC_LUT_WHITE_OFFSET_RED
+ regs
->crtcOffset
, 0xffff);
632 Write32(OUT
, EVERGREEN_DC_LUT_RW_MODE
, 0);
633 Write32(OUT
, EVERGREEN_DC_LUT_WRITE_EN_MASK
, 0x00000007);
635 Write32(OUT
, EVERGREEN_DC_LUT_RW_INDEX
, 0);
636 for (int i
= 0; i
< 256; i
++) {
637 Write32(OUT
, EVERGREEN_DC_LUT_30_COLOR
+ regs
->crtcOffset
,
638 (r
[i
] << 20) | (g
[i
] << 10) | (b
[i
] << 0));
641 if (info
.dceMajor
>= 5) {
642 Write32(OUT
, NI_DEGAMMA_CONTROL
+ regs
->crtcOffset
,
643 (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS
)
644 | NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS
)
645 | NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS
)
646 | NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS
)));
647 Write32(OUT
, NI_GAMUT_REMAP_CONTROL
+ regs
->crtcOffset
,
648 (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS
) |
649 NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS
)));
650 Write32(OUT
, NI_REGAMMA_CONTROL
+ regs
->crtcOffset
,
651 (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS
) |
652 NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS
)));
653 Write32(OUT
, NI_OUTPUT_CSC_CONTROL
+ regs
->crtcOffset
,
654 (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS
) |
655 NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS
)));
656 /* XXX match this to the depth of the crtc fmt block, move to modeset? */
657 Write32(OUT
, 0x6940 + regs
->crtcOffset
, 0);
663 display_avivo_crtc_load_lut(uint8 crtcID
)
665 radeon_shared_info
&info
= *gInfo
->shared_info
;
666 register_info
* regs
= gDisplay
[crtcID
]->regs
;
668 TRACE("%s: crtcID %" B_PRIu8
"\n", __func__
, crtcID
);
670 uint16
* r
= info
.color_data
;
674 Write32(OUT
, AVIVO_DC_LUTA_CONTROL
+ regs
->crtcOffset
, 0);
676 Write32(OUT
, AVIVO_DC_LUTA_BLACK_OFFSET_BLUE
+ regs
->crtcOffset
, 0);
677 Write32(OUT
, AVIVO_DC_LUTA_BLACK_OFFSET_GREEN
+ regs
->crtcOffset
, 0);
678 Write32(OUT
, AVIVO_DC_LUTA_BLACK_OFFSET_RED
+ regs
->crtcOffset
, 0);
680 Write32(OUT
, AVIVO_DC_LUTA_WHITE_OFFSET_BLUE
+ regs
->crtcOffset
, 0xffff);
681 Write32(OUT
, AVIVO_DC_LUTA_WHITE_OFFSET_GREEN
+ regs
->crtcOffset
, 0xffff);
682 Write32(OUT
, AVIVO_DC_LUTA_WHITE_OFFSET_RED
+ regs
->crtcOffset
, 0xffff);
684 Write32(OUT
, AVIVO_DC_LUT_RW_SELECT
, crtcID
);
685 Write32(OUT
, AVIVO_DC_LUT_RW_MODE
, 0);
686 Write32(OUT
, AVIVO_DC_LUT_WRITE_EN_MASK
, 0x0000003f);
688 Write32(OUT
, AVIVO_DC_LUT_RW_INDEX
, 0);
689 for (int i
= 0; i
< 256; i
++) {
690 Write32(OUT
, AVIVO_DC_LUT_30_COLOR
,
691 (r
[i
] << 20) | (g
[i
] << 10) | (b
[i
] << 0));
694 Write32(OUT
, AVIVO_D1GRPH_LUT_SEL
+ regs
->crtcOffset
, crtcID
);
699 display_crtc_fb_set(uint8 crtcID
, display_mode
* mode
)
701 radeon_shared_info
&info
= *gInfo
->shared_info
;
702 register_info
* regs
= gDisplay
[crtcID
]->regs
;
704 uint16
* r
= info
.color_data
;
709 if (info
.dceMajor
>= 4)
710 fbSwap
= EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE
);
712 fbSwap
= R600_D1GRPH_SWAP_ENDIAN_NONE
;
716 uint32 bytesPerPixel
;
719 switch (mode
->space
) {
723 if (info
.dceMajor
>= 4) {
724 fbFormat
= (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP
)
725 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED
));
727 fbFormat
= AVIVO_D1GRPH_CONTROL_DEPTH_8BPP
728 | AVIVO_D1GRPH_CONTROL_8BPP_INDEXED
;
730 // TODO: copy system color map into shared info
735 if (info
.dceMajor
>= 4) {
736 fbFormat
= (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP
)
737 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555
));
739 fbFormat
= AVIVO_D1GRPH_CONTROL_DEPTH_16BPP
740 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555
;
747 if (info
.dceMajor
>= 4) {
748 fbFormat
= (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP
)
749 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565
));
752 = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16
);
755 fbFormat
= AVIVO_D1GRPH_CONTROL_DEPTH_16BPP
756 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565
;
758 fbSwap
= R600_D1GRPH_SWAP_ENDIAN_16BIT
;
763 // default gamma table
765 for (int i
= 0; i
< 256; i
++) {
778 if (info
.dceMajor
>= 4) {
779 fbFormat
= (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP
)
780 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888
));
783 = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32
);
786 fbFormat
= AVIVO_D1GRPH_CONTROL_DEPTH_32BPP
787 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888
;
789 fbSwap
= R600_D1GRPH_SWAP_ENDIAN_32BIT
;
794 // default gamma table
796 for (int i
= 0; i
< 256; i
++) {
806 Write32(OUT
, regs
->vgaControl
, 0);
808 uint64 fbAddress
= gInfo
->fb
.vramStart
;
810 TRACE("%s: Framebuffer at: 0x%" B_PRIX64
"\n", __func__
, fbAddress
);
812 if (info
.chipsetID
>= RADEON_RV770
) {
813 TRACE("%s: Set SurfaceAddress High: 0x%" B_PRIX32
"\n",
814 __func__
, (fbAddress
>> 32) & 0xf);
816 Write32(OUT
, regs
->grphPrimarySurfaceAddrHigh
,
817 (fbAddress
>> 32) & 0xf);
818 Write32(OUT
, regs
->grphSecondarySurfaceAddrHigh
,
819 (fbAddress
>> 32) & 0xf);
822 TRACE("%s: Set SurfaceAddress: 0x%" B_PRIX64
"\n",
823 __func__
, (fbAddress
& 0xFFFFFFFF));
825 Write32(OUT
, regs
->grphPrimarySurfaceAddr
, (fbAddress
& 0xFFFFFFFF));
826 Write32(OUT
, regs
->grphSecondarySurfaceAddr
, (fbAddress
& 0xFFFFFFFF));
828 if (info
.chipsetID
>= RADEON_R600
) {
829 Write32(CRT
, regs
->grphControl
, fbFormat
);
830 Write32(CRT
, regs
->grphSwapControl
, fbSwap
);
833 // TODO: Technically if chip >= RS600
834 int largeAlign
= (info
.dceMajor
>= 2) ? 1 : 0;
836 // Align our framebuffer width
837 uint32 widthAligned
= mode
->virtual_width
;
838 uint32 pitchMask
= 0;
840 switch (bytesPerPixel
) {
842 pitchMask
= largeAlign
? 255 : 127;
845 pitchMask
= largeAlign
? 127 : 31;
849 pitchMask
= largeAlign
? 63 : 15;
852 widthAligned
+= pitchMask
;
853 widthAligned
&= ~pitchMask
;
855 TRACE("%s: fb: %" B_PRIu32
"x%" B_PRIu32
" (%" B_PRIu32
" bpp)\n", __func__
,
856 mode
->timing
.h_display
, mode
->timing
.v_display
, bitsPerPixel
);
857 TRACE("%s: fb pitch: %" B_PRIu32
" \n", __func__
, widthAligned
);
859 Write32(CRT
, regs
->grphSurfaceOffsetX
, 0);
860 Write32(CRT
, regs
->grphSurfaceOffsetY
, 0);
861 Write32(CRT
, regs
->grphXStart
, 0);
862 Write32(CRT
, regs
->grphYStart
, 0);
863 Write32(CRT
, regs
->grphXEnd
, mode
->virtual_width
);
864 Write32(CRT
, regs
->grphYEnd
, mode
->virtual_height
);
865 Write32(CRT
, regs
->grphPitch
, widthAligned
);
867 Write32(CRT
, regs
->grphEnable
, 1);
868 // Enable Frame buffer
870 Write32(CRT
, regs
->modeDesktopHeight
, mode
->virtual_height
);
872 uint32 viewportWidth
= mode
->timing
.h_display
;
873 uint32 viewportHeight
= (mode
->timing
.v_display
+ 1) & ~1;
875 Write32(CRT
, regs
->viewportStart
, 0);
876 Write32(CRT
, regs
->viewportSize
,
877 (viewportWidth
<< 16) | viewportHeight
);
880 if (info
.dceMajor
>= 4) {
882 = Read32(OUT
, EVERGREEN_GRPH_FLIP_CONTROL
+ regs
->crtcOffset
);
883 tmp
&= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN
;
884 Write32(OUT
, EVERGREEN_GRPH_FLIP_CONTROL
+ regs
->crtcOffset
, tmp
);
886 Write32(OUT
, EVERGREEN_MASTER_UPDATE_MODE
+ regs
->crtcOffset
, 0);
887 // Pageflip to happen anywhere in vblank
888 display_dce45_crtc_load_lut(crtcID
);
890 uint32 tmp
= Read32(OUT
, AVIVO_D1GRPH_FLIP_CONTROL
+ regs
->crtcOffset
);
891 tmp
&= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN
;
892 Write32(OUT
, AVIVO_D1GRPH_FLIP_CONTROL
+ regs
->crtcOffset
, tmp
);
894 Write32(OUT
, AVIVO_D1MODE_MASTER_UPDATE_MODE
+ regs
->crtcOffset
, 0);
895 // Pageflip to happen anywhere in vblank
896 display_avivo_crtc_load_lut(crtcID
);
899 // update shared info
900 gInfo
->shared_info
->bytes_per_row
= widthAligned
* bytesPerPixel
;
901 gInfo
->shared_info
->current_mode
= *mode
;
902 gInfo
->shared_info
->bits_per_pixel
= bitsPerPixel
;
907 display_crtc_set(uint8 crtcID
, display_mode
* mode
)
909 display_timing
& displayTiming
= mode
->timing
;
911 TRACE("%s called to do %dx%d\n",
912 __func__
, displayTiming
.h_display
, displayTiming
.v_display
);
914 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args
;
915 int index
= GetIndexIntoMasterTable(COMMAND
, SetCRTC_Timing
);
918 memset(&args
, 0, sizeof(args
));
920 args
.usH_Total
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_total
);
921 args
.usH_Disp
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_display
);
922 args
.usH_SyncStart
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_sync_start
);
923 args
.usH_SyncWidth
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_sync_end
924 - displayTiming
.h_sync_start
);
926 args
.usV_Total
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_total
);
927 args
.usV_Disp
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_display
);
928 args
.usV_SyncStart
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_sync_start
);
929 args
.usV_SyncWidth
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_sync_end
930 - displayTiming
.v_sync_start
);
932 args
.ucOverscanRight
= 0;
933 args
.ucOverscanLeft
= 0;
934 args
.ucOverscanBottom
= 0;
935 args
.ucOverscanTop
= 0;
937 if ((displayTiming
.flags
& B_POSITIVE_HSYNC
) == 0)
938 misc
|= ATOM_HSYNC_POLARITY
;
939 if ((displayTiming
.flags
& B_POSITIVE_VSYNC
) == 0)
940 misc
|= ATOM_VSYNC_POLARITY
;
942 args
.susModeMiscInfo
.usAccess
= B_HOST_TO_LENDIAN_INT16(misc
);
943 args
.ucCRTC
= crtcID
;
945 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
950 display_crtc_set_dtd(uint8 crtcID
, display_mode
* mode
)
952 display_timing
& displayTiming
= mode
->timing
;
954 TRACE("%s called to do %dx%d\n", __func__
,
955 displayTiming
.h_display
, displayTiming
.v_display
);
957 SET_CRTC_USING_DTD_TIMING_PARAMETERS args
;
958 int index
= GetIndexIntoMasterTable(COMMAND
, SetCRTC_UsingDTDTiming
);
961 memset(&args
, 0, sizeof(args
));
963 // Note: the code below assumes H & V borders are both zero
965 = MIN(displayTiming
.h_sync_start
, displayTiming
.h_display
);
967 = MAX(displayTiming
.h_sync_end
, displayTiming
.h_total
);
968 args
.usH_Size
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_display
);
969 args
.usH_Blanking_Time
= B_HOST_TO_LENDIAN_INT16(blankEnd
- blankStart
);
971 blankStart
= MIN(displayTiming
.v_sync_start
, displayTiming
.v_display
);
972 blankEnd
= MAX(displayTiming
.v_sync_end
, displayTiming
.v_total
);
973 args
.usV_Size
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_display
);
974 args
.usV_Blanking_Time
= B_HOST_TO_LENDIAN_INT16(blankEnd
- blankStart
);
976 args
.usH_SyncOffset
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_sync_start
977 - displayTiming
.h_display
);
978 args
.usH_SyncWidth
= B_HOST_TO_LENDIAN_INT16(displayTiming
.h_sync_end
979 - displayTiming
.h_sync_start
);
981 args
.usV_SyncOffset
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_sync_start
982 - displayTiming
.v_display
);
983 args
.usV_SyncWidth
= B_HOST_TO_LENDIAN_INT16(displayTiming
.v_sync_end
984 - displayTiming
.v_sync_start
);
989 if ((displayTiming
.flags
& B_POSITIVE_HSYNC
) == 0)
990 misc
|= ATOM_HSYNC_POLARITY
;
991 if ((displayTiming
.flags
& B_POSITIVE_VSYNC
) == 0)
992 misc
|= ATOM_VSYNC_POLARITY
;
994 args
.susModeMiscInfo
.usAccess
= B_HOST_TO_LENDIAN_INT16(misc
);
995 args
.ucCRTC
= crtcID
;
997 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1002 display_crtc_ss(pll_info
* pll
, int command
)
1004 TRACE("%s\n", __func__
);
1005 radeon_shared_info
&info
= *gInfo
->shared_info
;
1007 if (command
== ATOM_ENABLE
) {
1008 if (pll
->ssPercentage
== 0) {
1009 TRACE("%s: ssPercentage 0, ignoring SS request\n", __func__
);
1012 if ((pll
->ssType
& ATOM_EXTERNAL_SS_MASK
) != 0) {
1013 TRACE("%s: external SS, ignoring SS request\n", __func__
);
1017 if (pll_usage_count(pll
->id
) > 1) {
1018 // TODO: Check if PLL has SS enabled on any other displays, if so
1019 // we need to also skip this function.
1020 TRACE("%s: TODO: shared PLL detected!\n", __func__
);
1024 int index
= GetIndexIntoMasterTable(COMMAND
, EnableSpreadSpectrumOnPPLL
);
1027 ENABLE_LVDS_SS_PARAMETERS lvds_ss
;
1028 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2
;
1029 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1
;
1030 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2
;
1031 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3
;
1034 union enableSS args
;
1035 memset(&args
, 0, sizeof(args
));
1037 if (info
.dceMajor
>= 5) {
1038 args
.v3
.usSpreadSpectrumAmountFrac
= B_HOST_TO_LENDIAN_INT16(0);
1039 args
.v3
.ucSpreadSpectrumType
1040 = pll
->ssType
& ATOM_SS_CENTRE_SPREAD_MODE_MASK
;
1043 args
.v3
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V3_P1PLL
;
1046 args
.v3
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V3_P2PLL
;
1049 args
.v3
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V3_DCPLL
;
1051 case ATOM_PPLL_INVALID
:
1054 ERROR("%s: BUG: Invalid PLL ID!\n", __func__
);
1057 args
.v3
.usSpreadSpectrumAmount
= B_HOST_TO_LENDIAN_INT16(pll
->ssAmount
);
1058 args
.v3
.usSpreadSpectrumStep
= B_HOST_TO_LENDIAN_INT16(pll
->ssStep
);
1059 args
.v3
.ucEnable
= command
;
1060 } else if (info
.dceMajor
>= 4) {
1061 args
.v2
.usSpreadSpectrumPercentage
1062 = B_HOST_TO_LENDIAN_INT16(pll
->ssPercentage
);
1063 args
.v2
.ucSpreadSpectrumType
1064 = pll
->ssType
& ATOM_SS_CENTRE_SPREAD_MODE_MASK
;
1067 args
.v2
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V2_P1PLL
;
1070 args
.v2
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V3_P2PLL
;
1073 args
.v2
.ucSpreadSpectrumType
|= ATOM_PPLL_SS_TYPE_V3_DCPLL
;
1075 case ATOM_PPLL_INVALID
:
1078 ERROR("%s: BUG: Invalid PLL ID!\n", __func__
);
1081 args
.v2
.usSpreadSpectrumAmount
= B_HOST_TO_LENDIAN_INT16(pll
->ssAmount
);
1082 args
.v2
.usSpreadSpectrumStep
= B_HOST_TO_LENDIAN_INT16(pll
->ssStep
);
1083 args
.v2
.ucEnable
= command
;
1084 } else if (info
.dceMajor
>= 3) {
1085 args
.v1
.usSpreadSpectrumPercentage
1086 = B_HOST_TO_LENDIAN_INT16(pll
->ssPercentage
);
1087 args
.v1
.ucSpreadSpectrumType
1088 = pll
->ssType
& ATOM_SS_CENTRE_SPREAD_MODE_MASK
;
1089 args
.v1
.ucSpreadSpectrumStep
= pll
->ssStep
;
1090 args
.v1
.ucSpreadSpectrumDelay
= pll
->ssDelay
;
1091 args
.v1
.ucSpreadSpectrumRange
= pll
->ssRange
;
1092 args
.v1
.ucPpll
= pll
->id
;
1093 args
.v1
.ucEnable
= command
;
1094 } else if (info
.dceMajor
>= 2) {
1095 if (command
== ATOM_DISABLE
) {
1096 radeon_gpu_ss_control(pll
, false);
1099 args
.lvds_ss_2
.usSpreadSpectrumPercentage
1100 = B_HOST_TO_LENDIAN_INT16(pll
->ssPercentage
);
1101 args
.lvds_ss_2
.ucSpreadSpectrumType
1102 = pll
->ssType
& ATOM_SS_CENTRE_SPREAD_MODE_MASK
;
1103 args
.lvds_ss_2
.ucSpreadSpectrumStep
= pll
->ssStep
;
1104 args
.lvds_ss_2
.ucSpreadSpectrumDelay
= pll
->ssDelay
;
1105 args
.lvds_ss_2
.ucSpreadSpectrumRange
= pll
->ssRange
;
1106 args
.lvds_ss_2
.ucEnable
= command
;
1108 ERROR("%s: TODO: Old card SS control\n", __func__
);
1112 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1117 display_crtc_power(uint8 crtcID
, int command
)
1119 TRACE("%s\n", __func__
);
1120 int index
= GetIndexIntoMasterTable(COMMAND
, EnableCRTC
);
1121 ENABLE_CRTC_PS_ALLOCATION args
;
1123 memset(&args
, 0, sizeof(args
));
1125 args
.ucCRTC
= crtcID
;
1126 args
.ucEnable
= command
;
1128 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);
1133 display_crtc_memreq(uint8 crtcID
, int command
)
1135 TRACE("%s\n", __func__
);
1136 int index
= GetIndexIntoMasterTable(COMMAND
, EnableCRTCMemReq
);
1137 ENABLE_CRTC_PS_ALLOCATION args
;
1139 memset(&args
, 0, sizeof(args
));
1141 args
.ucCRTC
= crtcID
;
1142 args
.ucEnable
= command
;
1144 atom_execute_table(gAtomContext
, index
, (uint32
*)&args
);