* there is only one DDC channel on DVI-I connectors. as such

we get valid EDID data for two physical connectors (one analog, one digital)
  Check for load on the analog or assume digital and keep rolling as normal
* style fix, rename bios_*_scratch to biosScratch*


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42847 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexander von Gluck IV
2011-10-13 17:48:22 +00:00
parent 951b5e5147
commit 53aac74407
4 changed files with 166 additions and 65 deletions
+12 -12
View File
@@ -33,28 +33,28 @@ radeon_bios_init_scratch()
{
radeon_shared_info &info = *gInfo->shared_info;
uint32 bios_2_scratch;
uint32 bios_6_scratch;
uint32 biosScratch2;
uint32 biosScratch6;
if (info.device_chipset >= RADEON_R600) {
bios_2_scratch = Read32(OUT, R600_BIOS_2_SCRATCH);
bios_6_scratch = Read32(OUT, R600_BIOS_6_SCRATCH);
biosScratch2 = Read32(OUT, R600_BIOS_2_SCRATCH);
biosScratch6 = Read32(OUT, R600_BIOS_6_SCRATCH);
} else {
bios_2_scratch = Read32(OUT, RADEON_BIOS_2_SCRATCH);
bios_6_scratch = Read32(OUT, RADEON_BIOS_6_SCRATCH);
biosScratch2 = Read32(OUT, RADEON_BIOS_2_SCRATCH);
biosScratch6 = Read32(OUT, RADEON_BIOS_6_SCRATCH);
}
bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
biosScratch2 &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
// bios should control backlight
bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
biosScratch6 |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
// bios shouldn't handle mode switching
if (info.device_chipset >= RADEON_R600) {
Write32(OUT, R600_BIOS_2_SCRATCH, bios_2_scratch);
Write32(OUT, R600_BIOS_6_SCRATCH, bios_6_scratch);
Write32(OUT, R600_BIOS_2_SCRATCH, biosScratch2);
Write32(OUT, R600_BIOS_6_SCRATCH, biosScratch6);
} else {
Write32(OUT, RADEON_BIOS_2_SCRATCH, bios_2_scratch);
Write32(OUT, RADEON_BIOS_6_SCRATCH, bios_6_scratch);
Write32(OUT, RADEON_BIOS_2_SCRATCH, biosScratch2);
Write32(OUT, RADEON_BIOS_6_SCRATCH, biosScratch6);
}
}
+14 -7
View File
@@ -651,15 +651,23 @@ detect_displays()
for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
if (gConnector[id]->valid == false)
continue;
// TODO : currently we skip TV connectors during detection
if (gConnector[id]->encoder.isTV == true)
continue;
if (displayIndex >= MAX_DISPLAY)
continue;
if (radeon_gpu_read_edid(id, &gDisplay[displayIndex]->edid_info)) {
if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
|| gConnector[id]->encoder.type == VIDEO_ENCODER_DAC) {
// analog? with valid EDID? lets make sure there is load.
// There is only one ddc communications path on DVI-I
if (encoder_analog_load_detect(id) != true) {
TRACE("%s: no analog load on EDID valid connector "
"#%" B_PRIu32 "\n", __func__);
continue;
}
}
gDisplay[displayIndex]->active = true;
// set this display as active
gDisplay[displayIndex]->connectorIndex = id;
// set physical connector index from gConnector
@@ -688,7 +696,6 @@ detect_displays()
}
}
return B_OK;
}
@@ -814,7 +821,7 @@ display_crtc_blank(uint8 crtcID, int command)
args.ucCRTC = crtcID;
args.ucBlanking = command;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
@@ -1025,7 +1032,7 @@ display_crtc_set_dtd(uint8 crtcID, display_mode *mode)
args.susModeMiscInfo.usAccess = B_HOST_TO_LENDIAN_INT16(misc);
args.ucCRTC = crtcID;
atom_execute_table(gAtomContext, index, (uint32 *)&args);
atom_execute_table(gAtomContext, index, (uint32*)&args);
}
+139 -46
View File
@@ -373,6 +373,99 @@ encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
}
bool
encoder_analog_load_detect(uint8 connectorIndex)
{
uint32 encoderFlags = gConnector[connectorIndex]->encoder.flags;
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
if ((encoderFlags & ATOM_DEVICE_TV_SUPPORT) == 0
&& (encoderFlags & ATOM_DEVICE_CV_SUPPORT) == 0
&& (encoderFlags & ATOM_DEVICE_CRT_SUPPORT) == 0) {
ERROR("%s: executed on non-dac device connector #%" B_PRIu8 "\n",
__func__, connectorIndex);
return false;
}
// *** tell the card we want to do a DAC detection
DAC_LOAD_DETECTION_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
uint8 tableMajor;
uint8 tableMinor;
memset(&args, 0, sizeof(args));
if (atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor)
!= B_OK) {
ERROR("%s: failed getting AtomBIOS header for DAC_LoadDetection\n",
__func__);
return false;
}
args.sDacload.ucMisc = 0;
if (encoderID == ENCODER_OBJECT_ID_INTERNAL_DAC1
|| encoderID == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) {
args.sDacload.ucDacType = ATOM_DAC_A;
} else {
args.sDacload.ucDacType = ATOM_DAC_B;
}
if ((encoderFlags & ATOM_DEVICE_CRT1_SUPPORT) != 0) {
args.sDacload.usDeviceID
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT1_SUPPORT);
atom_execute_table(gAtomContext, index, (uint32*)&args);
uint32 biosScratch0 = Read32(OUT, R600_BIOS_0_SCRATCH);
if ((biosScratch0 & ATOM_S0_CRT1_MASK) != 0)
return true;
} else if ((encoderFlags & ATOM_DEVICE_CRT2_SUPPORT) != 0) {
args.sDacload.usDeviceID
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT2_SUPPORT);
atom_execute_table(gAtomContext, index, (uint32*)&args);
uint32 biosScratch0 = Read32(OUT, R600_BIOS_0_SCRATCH);
if ((biosScratch0 & ATOM_S0_CRT2_MASK) != 0)
return true;
} else if ((encoderFlags & ATOM_DEVICE_CV_SUPPORT) != 0) {
args.sDacload.usDeviceID
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CV_SUPPORT);
if (tableMinor >= 3)
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
atom_execute_table(gAtomContext, index, (uint32*)&args);
uint32 biosScratch0 = Read32(OUT, R600_BIOS_0_SCRATCH);
if ((biosScratch0 & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A)) != 0)
return true;
} else if ((encoderFlags & ATOM_DEVICE_TV1_SUPPORT) != 0) {
args.sDacload.usDeviceID
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_TV1_SUPPORT);
if (tableMinor >= 3)
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
atom_execute_table(gAtomContext, index, (uint32*)&args);
uint32 biosScratch0 = Read32(OUT, R600_BIOS_0_SCRATCH);
if ((biosScratch0
& (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) != 0) {
return true; /* Composite connected */
} else if ((biosScratch0
& (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) != 0) {
return true; /* S-Video connected */
}
}
return false;
}
void
encoder_crtc_scratch(uint8 crtcID)
{
@@ -382,43 +475,43 @@ encoder_crtc_scratch(uint8 crtcID)
uint32 encoderFlags = gConnector[connectorIndex]->encoder.flags;
// TODO : r500
uint32 bios_3_scratch = Read32(OUT, R600_BIOS_3_SCRATCH);
uint32 biosScratch3 = Read32(OUT, R600_BIOS_3_SCRATCH);
if ((encoderFlags & ATOM_DEVICE_TV1_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 18);
biosScratch3 &= ~ATOM_S3_TV1_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 18);
}
if ((encoderFlags & ATOM_DEVICE_CV_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 24);
biosScratch3 &= ~ATOM_S3_CV_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 24);
}
if ((encoderFlags & ATOM_DEVICE_CRT1_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 16);
biosScratch3 &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 16);
}
if ((encoderFlags & ATOM_DEVICE_CRT2_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 20);
biosScratch3 &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 20);
}
if ((encoderFlags & ATOM_DEVICE_LCD1_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 17);
biosScratch3 &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 17);
}
if ((encoderFlags & ATOM_DEVICE_DFP1_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 19);
biosScratch3 &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 19);
}
if ((encoderFlags & ATOM_DEVICE_DFP2_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 23);
biosScratch3 &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 23);
}
if ((encoderFlags & ATOM_DEVICE_DFP3_SUPPORT) != 0) {
bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
bios_3_scratch |= (crtcID << 25);
biosScratch3 &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
biosScratch3 |= (crtcID << 25);
}
// TODO : r500
Write32(OUT, R600_BIOS_3_SCRATCH, bios_3_scratch);
Write32(OUT, R600_BIOS_3_SCRATCH, biosScratch3);
}
@@ -431,69 +524,69 @@ encoder_dpms_scratch(uint8 crtcID, bool power)
uint32 encoderFlags = gConnector[connectorIndex]->encoder.flags;
// TODO : r500
uint32 bios_2_scratch = Read32(OUT, R600_BIOS_2_SCRATCH);
uint32 biosScratch2 = Read32(OUT, R600_BIOS_2_SCRATCH);
if ((encoderFlags & ATOM_DEVICE_TV1_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_TV1_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
biosScratch2 |= ATOM_S2_TV1_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_CV_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_CV_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
biosScratch2 |= ATOM_S2_CV_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_CRT1_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_CRT1_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
biosScratch2 |= ATOM_S2_CRT1_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_CRT2_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_CRT2_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
biosScratch2 |= ATOM_S2_CRT2_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_LCD1_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_LCD1_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
biosScratch2 |= ATOM_S2_LCD1_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_DFP1_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_DFP1_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
biosScratch2 |= ATOM_S2_DFP1_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_DFP2_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_DFP2_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
biosScratch2 |= ATOM_S2_DFP2_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_DFP3_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_DFP3_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
biosScratch2 |= ATOM_S2_DFP3_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_DFP4_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_DFP4_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;
biosScratch2 |= ATOM_S2_DFP4_DPMS_STATE;
}
if ((encoderFlags & ATOM_DEVICE_DFP5_SUPPORT) != 0) {
if (power == true)
bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;
biosScratch2 &= ~ATOM_S2_DFP5_DPMS_STATE;
else
bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;
biosScratch2 |= ATOM_S2_DFP5_DPMS_STATE;
}
Write32(OUT, R600_BIOS_2_SCRATCH, bios_2_scratch);
Write32(OUT, R600_BIOS_2_SCRATCH, biosScratch2);
}
@@ -588,15 +681,15 @@ void
encoder_output_lock(bool lock)
{
TRACE("%s: %s\n", __func__, lock ? "true" : "false");
uint32 bios_6_scratch = Read32(OUT, R600_BIOS_6_SCRATCH);
uint32 biosScratch6 = Read32(OUT, R600_BIOS_6_SCRATCH);
if (lock) {
bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
bios_6_scratch &= ~ATOM_S6_ACC_MODE;
biosScratch6 |= ATOM_S6_CRITICAL_STATE;
biosScratch6 &= ~ATOM_S6_ACC_MODE;
} else {
bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
bios_6_scratch |= ATOM_S6_ACC_MODE;
biosScratch6 &= ~ATOM_S6_CRITICAL_STATE;
biosScratch6 |= ATOM_S6_ACC_MODE;
}
Write32(OUT, R600_BIOS_6_SCRATCH, bios_6_scratch);
Write32(OUT, R600_BIOS_6_SCRATCH, biosScratch6);
}
@@ -13,6 +13,7 @@ void encoder_assign_crtc(uint8 crt_id);
void encoder_mode_set(uint8 id, uint32 pixelClock);
status_t encoder_digital_setup(uint8 id, uint32 pixelClock, int command);
status_t encoder_analog_setup(uint8 id, uint32 pixelClock, int command);
bool encoder_analog_load_detect(uint8 connectorIndex);
void encoder_output_lock(bool lock);
void encoder_crtc_scratch(uint8 crtcID);
void encoder_dpms_scratch(uint8 crtcID, bool power);