* complete pll_set for all AtomBIOS revisions
* add update of crtc encoder scratch registers * rename id for more descriptive crtc_id * encoder dpms, BL on/off on lcd git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42828 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -37,7 +37,7 @@ union crtc_source_param {
|
||||
|
||||
|
||||
void
|
||||
encoder_assign_crtc(uint8 id)
|
||||
encoder_assign_crtc(uint8 crtc_id)
|
||||
{
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
|
||||
union crtc_source_param args;
|
||||
@@ -50,7 +50,7 @@ encoder_assign_crtc(uint8 id)
|
||||
!= B_OK)
|
||||
return;
|
||||
|
||||
uint16 connector_index = gDisplay[id]->connector_index;
|
||||
uint16 connector_index = gDisplay[crtc_id]->connector_index;
|
||||
uint16 encoder_id = gConnector[connector_index]->encoder.object_id;
|
||||
|
||||
switch (frev) {
|
||||
@@ -58,7 +58,7 @@ encoder_assign_crtc(uint8 id)
|
||||
switch (crev) {
|
||||
case 1:
|
||||
default:
|
||||
args.v1.ucCRTC = id;
|
||||
args.v1.ucCRTC = crtc_id;
|
||||
switch (encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||
@@ -102,7 +102,7 @@ encoder_assign_crtc(uint8 id)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
args.v2.ucCRTC = id;
|
||||
args.v2.ucCRTC = crtc_id;
|
||||
args.v2.ucEncodeMode
|
||||
= display_get_encoder_mode(connector_index);
|
||||
switch (encoder_id) {
|
||||
@@ -168,7 +168,8 @@ encoder_assign_crtc(uint8 id)
|
||||
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
|
||||
// TODO : encoder_crtc_scratch_regs?
|
||||
// update crtc encoder scratch register @ scratch 3
|
||||
encoder_crtc_scratch(crtc_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -365,6 +366,55 @@ encoder_analog_setup(uint8 id, uint32 pixelClock, int command)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
encoder_crtc_scratch(uint8 crtc_id)
|
||||
{
|
||||
TRACE("%s\n", __func__);
|
||||
|
||||
uint32 connector_index = gDisplay[crtc_id]->connector_index;
|
||||
uint32 encoder_flags = gConnector[connector_index]->encoder.flags;
|
||||
|
||||
// TODO : r500
|
||||
uint32 bios_3_scratch = Read32(OUT, R600_BIOS_3_SCRATCH);
|
||||
|
||||
if (encoder_flags & ATOM_DEVICE_TV1_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 18);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_CV_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 24);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_CRT1_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 16);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_CRT2_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 20);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_LCD1_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 17);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_DFP1_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 19);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_DFP2_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 23);
|
||||
}
|
||||
if (encoder_flags & ATOM_DEVICE_DFP3_SUPPORT) {
|
||||
bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
|
||||
bios_3_scratch |= (crtc_id << 25);
|
||||
}
|
||||
|
||||
// TODO : r500
|
||||
Write32(OUT, R600_BIOS_3_SCRATCH, bios_3_scratch);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
encoder_dpms_scratch(uint8 crtc_id, bool power)
|
||||
{
|
||||
@@ -448,6 +498,9 @@ encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode)
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
uint32 connector_index = gDisplay[crtc_id]->connector_index;
|
||||
uint32 encoder_flags = gConnector[connector_index]->encoder.flags;
|
||||
|
||||
switch (encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||
@@ -474,10 +527,10 @@ encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode)
|
||||
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||
// TODO : Laptop LCD special cases dpms set
|
||||
// if ATOM_DEVICE_LCD_SUPPORT, LCD1OutputControl
|
||||
// else...
|
||||
index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
|
||||
if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT)
|
||||
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
|
||||
else
|
||||
index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
|
||||
@@ -503,8 +556,10 @@ encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode)
|
||||
case B_DPMS_ON:
|
||||
args.ucAction = ATOM_ENABLE;
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
// TODO : ATOM_DEVICE_LCD_SUPPORT : args.ucAction = ATOM_LCD_BLON;
|
||||
// execute again
|
||||
if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT) {
|
||||
args.ucAction = ATOM_LCD_BLON;
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
}
|
||||
encoder_dpms_scratch(crtc_id, true);
|
||||
break;
|
||||
case B_DPMS_STAND_BY:
|
||||
@@ -512,8 +567,10 @@ encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode)
|
||||
case B_DPMS_OFF:
|
||||
args.ucAction = ATOM_DISABLE;
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
// TODO : ATOM_DEVICE_LCD_SUPPORT : args.ucAction = ATOM_LCD_BLOFF;
|
||||
// execute again
|
||||
if (encoder_flags & ATOM_DEVICE_LCD_SUPPORT) {
|
||||
args.ucAction = ATOM_LCD_BLOFF;
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
}
|
||||
encoder_dpms_scratch(crtc_id, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ 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);
|
||||
void encoder_output_lock(bool lock);
|
||||
void encoder_crtc_scratch(uint8 crtc_id);
|
||||
void encoder_dpms_scratch(uint8 crtc_id, bool power);
|
||||
void encoder_dpms_set(uint8 crtc_id, uint8 encoder_id, int mode);
|
||||
|
||||
|
||||
@@ -267,12 +267,14 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
||||
{
|
||||
uint32 connector_index = gDisplay[crtc_id]->connector_index;
|
||||
pll_info *pll = &gConnector[connector_index]->encoder.pll;
|
||||
|
||||
pll->pixel_clock = pixelClock;
|
||||
pll->id = pll_id;
|
||||
|
||||
// get any needed clock adjustments, set reference/post dividers, set flags
|
||||
uint32 adjustedClock = pll_adjust(pll, crtc_id);
|
||||
|
||||
// compute dividers, set flags
|
||||
pll_compute(pll);
|
||||
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
|
||||
@@ -283,6 +285,10 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
||||
uint8 crev;
|
||||
atom_parse_cmd_header(gAtomContext, index, &frev, &crev);
|
||||
|
||||
uint32 bpc = 8;
|
||||
// TODO : BPC == Digital Depth, EDID 1.4+ on digital displays
|
||||
// isn't in Haiku edid common code?
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
|
||||
@@ -318,6 +324,63 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
||||
= gConnector[connector_index]->encoder.object_id;
|
||||
args.v3.ucEncoderMode = display_get_encoder_mode(connector_index);
|
||||
break;
|
||||
case 5:
|
||||
args.v5.ucCRTC = crtc_id;
|
||||
args.v5.usPixelClock = B_HOST_TO_LENDIAN_INT16(adjustedClock / 10);
|
||||
args.v5.ucRefDiv = pll->reference_div;
|
||||
args.v5.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedback_div);
|
||||
args.v5.ulFbDivDecFrac
|
||||
= B_HOST_TO_LENDIAN_INT32(pll->feedback_div_frac * 100000);
|
||||
args.v5.ucPostDiv = pll->post_div;
|
||||
args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
|
||||
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
|
||||
// args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
|
||||
switch (bpc) {
|
||||
case 8:
|
||||
default:
|
||||
args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
|
||||
break;
|
||||
case 10:
|
||||
args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
|
||||
break;
|
||||
}
|
||||
args.v5.ucTransmitterID
|
||||
= gConnector[connector_index]->encoder.object_id;
|
||||
args.v5.ucEncoderMode
|
||||
= display_get_encoder_mode(connector_index);
|
||||
args.v5.ucPpll = pll_id;
|
||||
break;
|
||||
case 6:
|
||||
args.v6.ulDispEngClkFreq
|
||||
= B_HOST_TO_LENDIAN_INT32(crtc_id << 24 | adjustedClock / 10);
|
||||
args.v6.ucRefDiv = pll->reference_div;
|
||||
args.v6.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedback_div);
|
||||
args.v6.ulFbDivDecFrac
|
||||
= B_HOST_TO_LENDIAN_INT32(pll->feedback_div_frac * 100000);
|
||||
args.v6.ucPostDiv = pll->post_div;
|
||||
args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
|
||||
// if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
|
||||
// args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
|
||||
switch (bpc) {
|
||||
case 8:
|
||||
default:
|
||||
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
|
||||
break;
|
||||
case 10:
|
||||
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
|
||||
break;
|
||||
case 12:
|
||||
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
|
||||
break;
|
||||
case 16:
|
||||
args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
|
||||
break;
|
||||
}
|
||||
args.v6.ucTransmitterID
|
||||
= gConnector[connector_index]->encoder.object_id;
|
||||
args.v6.ucEncoderMode = display_get_encoder_mode(connector_index);
|
||||
args.v6.ucPpll = pll_id;
|
||||
break;
|
||||
default:
|
||||
TRACE("%s: ERROR: table version %d.%d TODO\n", __func__,
|
||||
frev, crev);
|
||||
|
||||
Reference in New Issue
Block a user