diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index ac71a183f0..25898c7834 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -154,6 +154,7 @@ typedef struct { uint16 objectID; uint32 type; uint32 flags; + uint32 lvdsFlags; uint16 gpioID; struct encoder_info encoder; // TODO struct radeon_hpd hpd; diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp b/src/add-ons/accelerants/radeon_hd/connector.cpp index 9134526789..4ecf50867e 100644 --- a/src/add-ons/accelerants/radeon_hd/connector.cpp +++ b/src/add-ons/accelerants/radeon_hd/connector.cpp @@ -195,9 +195,11 @@ connector_read_mode_lvds(uint32 connectorIndex, display_mode* mode) // Who cares. uint32 powerDelay = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.usOffDelayInMs); - uint32 lcdMisc = lvdsInfo->info.ucLVDS_Misc; #endif + // Store special lvds flags the encoder setup needs + gConnector[connectorIndex]->lvdsFlags = lvdsInfo->info.ucLVDS_Misc; + uint16 flags = B_LENDIAN_TO_HOST_INT16( lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess); diff --git a/src/add-ons/accelerants/radeon_hd/encoder.cpp b/src/add-ons/accelerants/radeon_hd/encoder.cpp index 0618d27c6d..d159d14b6e 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.cpp +++ b/src/add-ons/accelerants/radeon_hd/encoder.cpp @@ -397,6 +397,9 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command) return B_ERROR; } + uint32 lvdsFlags = gConnector[connectorIndex]->lvdsFlags; + bool isHdmi = gConnector[connectorIndex]->encoder.isHDMI; + // Prepare AtomBIOS command arguments union lvdsEncoderControl { LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; @@ -415,16 +418,15 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command) case 1: args.v1.ucMisc = 0; args.v1.ucAction = command; - if (0) // TODO: HDMI? + if (isHdmi) args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10); if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { - // TODO: laptop display support - //if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) - // args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; - //if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - // args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; + if ((lvdsFlags & ATOM_PANEL_MISC_DUAL) != 0) + args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; + if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0) + args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; } else { //if (dig->linkb) // args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; @@ -442,7 +444,7 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command) //if (dig->coherent_mode) // args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; } - if (0) // TODO: HDMI? + if (isHdmi) args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v2.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10); args.v2.ucTruncate = 0; @@ -450,26 +452,27 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command) args.v2.ucTemporal = 0; args.v2.ucFRC = 0; if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { - // TODO: laptop display support - //if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) - // args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; - //if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { - args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; - //if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - // args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; - //} - //if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { - // args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; - // if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) { - // args.v2.ucTemporal - // |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; - // } - // if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) - // & 0x3) == 2) { - // args.v2.ucTemporal - // |= PANEL_ENCODER_TEMPORAL_LEVEL_4; - // } - //} + if ((lvdsFlags & ATOM_PANEL_MISC_DUAL) != 0) + args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; + if ((lvdsFlags & ATOM_PANEL_MISC_SPATIAL) != 0) { + args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; + if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0) { + args.v2.ucSpatial + |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; + } + } + + if ((lvdsFlags & ATOM_PANEL_MISC_TEMPORAL) != 0) + args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; + if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0) { + args.v2.ucTemporal + |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; + } + if (((lvdsFlags >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) + & 0x3) == 2) { + args.v2.ucTemporal + |= PANEL_ENCODER_TEMPORAL_LEVEL_4; + } } else { //if (dig->linkb) // args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; @@ -1436,18 +1439,18 @@ encoder_dpms_set(uint8 crtcID, int mode) case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: encoder_dpms_set_dig(crtcID, mode); - // We don't call OutputControl on DIG return; case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DDI: index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - // TODO: encoder dpms set newer cards - // If DCE5, dvo true - // If DCE3, dig true - // else... - index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); + if (info.dceMajor >= 5) + encoder_dpms_set_dvo(crtcID, mode); + else if (info.dceMajor >= 3) + encoder_dpms_set_dig(crtcID, mode); + else + index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); break; case ENCODER_OBJECT_ID_INTERNAL_LVDS: index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); @@ -1627,6 +1630,13 @@ encoder_dpms_set_external(uint8 crtcID, int mode) } +void +encoder_dpms_set_dvo(uint8 crtcID, int mode) +{ + ERROR("%s: TODO, dvo encoder dpms stub\n", __func__); +} + + void encoder_output_lock(bool lock) { diff --git a/src/add-ons/accelerants/radeon_hd/encoder.h b/src/add-ons/accelerants/radeon_hd/encoder.h index abbca82cbf..d7c150eeeb 100644 --- a/src/add-ons/accelerants/radeon_hd/encoder.h +++ b/src/add-ons/accelerants/radeon_hd/encoder.h @@ -36,6 +36,7 @@ void encoder_crtc_scratch(uint8 crtcID); void encoder_dpms_scratch(uint8 crtcID, bool power); void encoder_dpms_set(uint8 crtcID, int mode); void encoder_dpms_set_dig(uint8 crtcID, int mode); +void encoder_dpms_set_dvo(uint8 crtcID, int mode); void encoder_dpms_set_external(uint8 crtcID, int mode); const char* encoder_name_lookup(uint32 encoderID);