radeon_hd: lvds, dvo, and hdmi encoder improvements

* Begin storing the lcd flags in lvds info call as the
  encoder needs them.
* Fill out laptop / lvds todo in encoder code.
* Stub out dvo encoder calls, not sure use cases for dvo.
This commit is contained in:
Alexander von Gluck IV
2012-02-28 09:56:20 -06:00
parent 64ff3d1891
commit e766693eb0
4 changed files with 48 additions and 34 deletions
@@ -154,6 +154,7 @@ typedef struct {
uint16 objectID; uint16 objectID;
uint32 type; uint32 type;
uint32 flags; uint32 flags;
uint32 lvdsFlags;
uint16 gpioID; uint16 gpioID;
struct encoder_info encoder; struct encoder_info encoder;
// TODO struct radeon_hpd hpd; // TODO struct radeon_hpd hpd;
@@ -195,9 +195,11 @@ connector_read_mode_lvds(uint32 connectorIndex, display_mode* mode)
// Who cares. // Who cares.
uint32 powerDelay uint32 powerDelay
= B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.usOffDelayInMs); = B_LENDIAN_TO_HOST_INT16(lvdsInfo->info.usOffDelayInMs);
uint32 lcdMisc = lvdsInfo->info.ucLVDS_Misc;
#endif #endif
// Store special lvds flags the encoder setup needs
gConnector[connectorIndex]->lvdsFlags = lvdsInfo->info.ucLVDS_Misc;
uint16 flags = B_LENDIAN_TO_HOST_INT16( uint16 flags = B_LENDIAN_TO_HOST_INT16(
lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess); lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess);
+43 -33
View File
@@ -397,6 +397,9 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command)
return B_ERROR; return B_ERROR;
} }
uint32 lvdsFlags = gConnector[connectorIndex]->lvdsFlags;
bool isHdmi = gConnector[connectorIndex]->encoder.isHDMI;
// Prepare AtomBIOS command arguments // Prepare AtomBIOS command arguments
union lvdsEncoderControl { union lvdsEncoderControl {
LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; LVDS_ENCODER_CONTROL_PS_ALLOCATION v1;
@@ -415,16 +418,15 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command)
case 1: case 1:
args.v1.ucMisc = 0; args.v1.ucMisc = 0;
args.v1.ucAction = command; args.v1.ucAction = command;
if (0) // TODO: HDMI? if (isHdmi)
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10); args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
// TODO: laptop display support if ((lvdsFlags & ATOM_PANEL_MISC_DUAL) != 0)
//if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
// args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0)
//if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
// args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
} else { } else {
//if (dig->linkb) //if (dig->linkb)
// args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_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) //if (dig->coherent_mode)
// args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; // args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
} }
if (0) // TODO: HDMI? if (isHdmi)
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v2.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10); args.v2.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
args.v2.ucTruncate = 0; args.v2.ucTruncate = 0;
@@ -450,26 +452,27 @@ encoder_digital_setup(uint32 connectorIndex, uint32 pixelClock, int command)
args.v2.ucTemporal = 0; args.v2.ucTemporal = 0;
args.v2.ucFRC = 0; args.v2.ucFRC = 0;
if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) { if ((encoderFlags & ATOM_DEVICE_LCD_SUPPORT) != 0) {
// TODO: laptop display support if ((lvdsFlags & ATOM_PANEL_MISC_DUAL) != 0)
//if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
// args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; if ((lvdsFlags & ATOM_PANEL_MISC_SPATIAL) != 0) {
//if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0) {
//if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) args.v2.ucSpatial
// args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; |= 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) { if ((lvdsFlags & ATOM_PANEL_MISC_TEMPORAL) != 0)
// args.v2.ucTemporal args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
// |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; if ((lvdsFlags & ATOM_PANEL_MISC_888RGB) != 0) {
// } args.v2.ucTemporal
// if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
// & 0x3) == 2) { }
// args.v2.ucTemporal if (((lvdsFlags >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT)
// |= PANEL_ENCODER_TEMPORAL_LEVEL_4; & 0x3) == 2) {
// } args.v2.ucTemporal
//} |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
}
} else { } else {
//if (dig->linkb) //if (dig->linkb)
// args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_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_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
encoder_dpms_set_dig(crtcID, mode); encoder_dpms_set_dig(crtcID, mode);
// We don't call OutputControl on DIG
return; return;
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
// TODO: encoder dpms set newer cards if (info.dceMajor >= 5)
// If DCE5, dvo true encoder_dpms_set_dvo(crtcID, mode);
// If DCE3, dig true else if (info.dceMajor >= 3)
// else... encoder_dpms_set_dig(crtcID, mode);
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); else
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_LVDS: case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); 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 void
encoder_output_lock(bool lock) encoder_output_lock(bool lock)
{ {
@@ -36,6 +36,7 @@ void encoder_crtc_scratch(uint8 crtcID);
void encoder_dpms_scratch(uint8 crtcID, bool power); void encoder_dpms_scratch(uint8 crtcID, bool power);
void encoder_dpms_set(uint8 crtcID, int mode); void encoder_dpms_set(uint8 crtcID, int mode);
void encoder_dpms_set_dig(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); void encoder_dpms_set_external(uint8 crtcID, int mode);
const char* encoder_name_lookup(uint32 encoderID); const char* encoder_name_lookup(uint32 encoderID);