* reformulate display and connector storage to match AtomBIOS requirements
* each active gDisplay references a gConnector index * add atombios DAC sense.. this really won't be the main call used... AtomBIOS expects you to attempt an EDID read to detect connected displays * remove old manual DACSense * next we attempt to add ddc / edid git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42705 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -141,7 +141,7 @@ struct pll_info {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
bool valid;
|
bool valid;
|
||||||
uint16 line_mux;
|
uint16 line_mux;
|
||||||
uint16 devices;
|
uint16 connector_flags;
|
||||||
uint32 connector_type;
|
uint32 connector_type;
|
||||||
uint16 connector_object_id;
|
uint16 connector_object_id;
|
||||||
uint32 encoder_type;
|
uint32 encoder_type;
|
||||||
@@ -153,8 +153,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool active;
|
bool active;
|
||||||
uint32 connection_type;
|
uint32 connector_index; // matches connector id in connector_info
|
||||||
uint8 connection_id;
|
|
||||||
register_info *regs;
|
register_info *regs;
|
||||||
bool found_ranges;
|
bool found_ranges;
|
||||||
uint32 vfreq_max;
|
uint32 vfreq_max;
|
||||||
|
|||||||
@@ -23,69 +23,75 @@ extern "C" void _sPrintf(const char *format, ...);
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DACSense(uint8 dacIndex)
|
dac_sense(uint32 connector_id)
|
||||||
{
|
{
|
||||||
uint32 dacOffset = dacIndex == 1 ? REG_DACB_OFFSET : REG_DACA_OFFSET;
|
uint16 flags = gConnector[connector_id]->connector_flags;
|
||||||
|
|
||||||
// Backup current DAC values
|
if (flags & (ATOM_DEVICE_CRT_SUPPORT
|
||||||
uint32 compEnable = Read32(OUT, dacOffset + DACA_COMPARATOR_ENABLE);
|
| ATOM_DEVICE_CV_SUPPORT
|
||||||
uint32 control1 = Read32(OUT, dacOffset + DACA_CONTROL1);
|
| ATOM_DEVICE_TV_SUPPORT)) {
|
||||||
uint32 control2 = Read32(OUT, dacOffset + DACA_CONTROL2);
|
|
||||||
uint32 detectControl = Read32(OUT, dacOffset + DACA_AUTODETECT_CONTROL);
|
|
||||||
uint32 enable = Read32(OUT, dacOffset + DACA_ENABLE);
|
|
||||||
|
|
||||||
Write32(OUT, dacOffset + DACA_ENABLE, 1);
|
DAC_LOAD_DETECTION_PS_ALLOCATION args;
|
||||||
// Acknowledge autodetect
|
int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
|
||||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_INT_CONTROL, 0x01, 0x01);
|
uint8 frev, crev;
|
||||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL, 0, 0x00000003);
|
memset(&args, 0, sizeof(args));
|
||||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00000001);
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0, 0x00ff0000);
|
|
||||||
|
|
||||||
Write32(OUT, dacOffset + DACA_FORCE_DATA, 0);
|
if (!atom_parse_cmd_header(gAtomContext, index, &frev, &crev))
|
||||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, 0x00000001, 0x0000001);
|
return false;
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
args.sDacload.ucMisc = 0;
|
||||||
0x00070000, 0x00070101);
|
|
||||||
Write32(OUT, dacOffset + DACA_CONTROL1, 0x00050802);
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x00000001);
|
|
||||||
// Shutdown Bandgap voltage reference
|
|
||||||
|
|
||||||
snooze(5);
|
if ((flags & ENCODER_OBJECT_ID_INTERNAL_DAC1)
|
||||||
|
|| (flags & ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
|
||||||
|
args.sDacload.ucDacType = ATOM_DAC_A;
|
||||||
|
else
|
||||||
|
args.sDacload.ucDacType = ATOM_DAC_B;
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
|
if (flags & ATOM_DEVICE_CRT1_SUPPORT) {
|
||||||
// Shutdown RGB
|
args.sDacload.usDeviceID
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT1_SUPPORT);
|
||||||
|
} else if (flags & ATOM_DEVICE_CRT2_SUPPORT) {
|
||||||
|
args.sDacload.usDeviceID
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CRT2_SUPPORT);
|
||||||
|
} else if (flags & ATOM_DEVICE_CV_SUPPORT) {
|
||||||
|
args.sDacload.usDeviceID
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_CV_SUPPORT);
|
||||||
|
if (crev >= 3)
|
||||||
|
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
|
||||||
|
} else if (flags & ATOM_DEVICE_TV1_SUPPORT) {
|
||||||
|
args.sDacload.usDeviceID
|
||||||
|
= B_HOST_TO_LENDIAN_INT16(ATOM_DEVICE_TV1_SUPPORT);
|
||||||
|
if (crev >= 3)
|
||||||
|
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
|
||||||
|
}
|
||||||
|
|
||||||
Write32(OUT, dacOffset + DACA_FORCE_DATA, 0x1e6);
|
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||||
// 486 out of 1024
|
|
||||||
snooze(200);
|
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0x01010100, 0x01010100);
|
uint32 bios_0_scratch;
|
||||||
// Enable RGB
|
|
||||||
snooze(88);
|
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_POWERDOWN, 0, 0x01010100);
|
bios_0_scratch = Read32(OUT, R600_BIOS_0_SCRATCH);
|
||||||
// Shutdown RGB
|
|
||||||
|
|
||||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
if (flags & ATOM_DEVICE_CRT1_SUPPORT) {
|
||||||
0x00000100, 0x00000100);
|
if (bios_0_scratch & ATOM_S0_CRT1_MASK)
|
||||||
|
return true;
|
||||||
snooze(100);
|
}
|
||||||
|
if (flags & ATOM_DEVICE_CRT2_SUPPORT) {
|
||||||
// Get detected RGB channels
|
if (bios_0_scratch & ATOM_S0_CRT2_MASK)
|
||||||
// If only G is found, it could be a monochrome monitor, but we
|
return true;
|
||||||
// don't bother checking.
|
}
|
||||||
uint8 out = (Read32(OUT, dacOffset + DACA_COMPARATOR_OUTPUT) & 0x0E) >> 1;
|
if (flags & ATOM_DEVICE_CV_SUPPORT) {
|
||||||
|
if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
|
||||||
// Restore stored DAC values
|
return true;
|
||||||
Write32Mask(OUT, dacOffset + DACA_COMPARATOR_ENABLE,
|
}
|
||||||
compEnable, 0x00FFFFFF);
|
if (flags & ATOM_DEVICE_TV1_SUPPORT) {
|
||||||
Write32(OUT, dacOffset + DACA_CONTROL1, control1);
|
if (bios_0_scratch
|
||||||
Write32Mask(OUT, dacOffset + DACA_CONTROL2, control2, 0x000001FF);
|
& (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
|
||||||
Write32Mask(OUT, dacOffset + DACA_AUTODETECT_CONTROL,
|
return true; /* CTV */
|
||||||
detectControl, 0x000000FF);
|
else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
|
||||||
Write32Mask(OUT, dacOffset + DACA_ENABLE, enable, 0x000000FF);
|
return true; /* STV */
|
||||||
|
}
|
||||||
return (out == 0x7);
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#define FORMAT_TvCV 0x3
|
#define FORMAT_TvCV 0x3
|
||||||
|
|
||||||
|
|
||||||
bool DACSense(uint8 dacIndex);
|
bool dac_sense(uint32 connector_id);
|
||||||
void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
|
void DACGetElectrical(uint8 type, uint8 dac, uint8 *bandgap, uint8 *whitefine);
|
||||||
void DACSet(uint8 dacIndex, uint32 crtid);
|
void DACSet(uint8 dacIndex, uint32 crtid);
|
||||||
void DACPower(uint8 dacIndex, int mode);
|
void DACPower(uint8 dacIndex, int mode);
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ detect_crt_ranges(uint32 crtid)
|
|||||||
{
|
{
|
||||||
edid1_info *edid = &gInfo->shared_info->edid_info;
|
edid1_info *edid = &gInfo->shared_info->edid_info;
|
||||||
|
|
||||||
// TODO : VESA edid is just for primary monitor?
|
// TODO : use radeon ddc to get to connector EDID instead of VESA
|
||||||
|
|
||||||
// Scan each VESA EDID description for monitor ranges
|
// Scan each VESA EDID description for monitor ranges
|
||||||
for (uint32 index = 0; index < EDID1_NUM_DETAILED_MONITOR_DESC; index++) {
|
for (uint32 index = 0; index < EDID1_NUM_DETAILED_MONITOR_DESC; index++) {
|
||||||
@@ -292,7 +292,7 @@ detect_connectors_legacy()
|
|||||||
gConnector[i]->connector_type = VIDEO_CONNECTOR_VGA;
|
gConnector[i]->connector_type = VIDEO_CONNECTOR_VGA;
|
||||||
|
|
||||||
gConnector[i]->valid = true;
|
gConnector[i]->valid = true;
|
||||||
gConnector[i]->devices = (1 << i);
|
gConnector[i]->connector_flags = (1 << i);
|
||||||
|
|
||||||
// TODO : add the encoder
|
// TODO : add the encoder
|
||||||
#if 0
|
#if 0
|
||||||
@@ -383,8 +383,9 @@ detect_connectors()
|
|||||||
|
|
||||||
uint32 connector_type;
|
uint32 connector_type;
|
||||||
uint16 connector_object_id;
|
uint16 connector_object_id;
|
||||||
|
uint16 connector_flags = B_LENDIAN_TO_HOST_INT16(path->usDeviceTag);
|
||||||
|
|
||||||
if (device_support & B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)) {
|
if (device_support & connector_flags) {
|
||||||
uint8 con_obj_id = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
uint8 con_obj_id = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
||||||
& OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
& OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
|
||||||
|
|
||||||
@@ -395,8 +396,7 @@ detect_connectors()
|
|||||||
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
// = (B_LENDIAN_TO_HOST_INT16(path->usConnObjectId)
|
||||||
// & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
// & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
||||||
|
|
||||||
if (B_LENDIAN_TO_HOST_INT16(path->usDeviceTag)
|
if (connector_flags == ATOM_DEVICE_CV_SUPPORT) {
|
||||||
== ATOM_DEVICE_CV_SUPPORT) {
|
|
||||||
TRACE("%s: Path #%" B_PRId32 ": skipping component video.\n",
|
TRACE("%s: Path #%" B_PRId32 ": skipping component video.\n",
|
||||||
__func__, i);
|
__func__, i);
|
||||||
continue;
|
continue;
|
||||||
@@ -465,15 +465,13 @@ detect_connectors()
|
|||||||
}
|
}
|
||||||
uint32 encoder_id = (encoder_obj & OBJECT_ID_MASK)
|
uint32 encoder_id = (encoder_obj & OBJECT_ID_MASK)
|
||||||
>> OBJECT_ID_SHIFT;
|
>> OBJECT_ID_SHIFT;
|
||||||
uint32 encoder_support
|
|
||||||
= B_LENDIAN_TO_HOST_INT16(path->usDeviceTag);
|
|
||||||
|
|
||||||
switch(encoder_id) {
|
switch(encoder_id) {
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||||
if (encoder_support
|
if (connector_flags
|
||||||
& ATOM_DEVICE_LCD_SUPPORT) {
|
& ATOM_DEVICE_LCD_SUPPORT) {
|
||||||
encoder_type = VIDEO_ENCODER_LVDS;
|
encoder_type = VIDEO_ENCODER_LVDS;
|
||||||
// radeon_atombios_get_lvds_info
|
// radeon_atombios_get_lvds_info
|
||||||
@@ -499,10 +497,10 @@ detect_connectors()
|
|||||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||||
if (encoder_support
|
if (connector_flags
|
||||||
& ATOM_DEVICE_LCD_SUPPORT) {
|
& ATOM_DEVICE_LCD_SUPPORT) {
|
||||||
encoder_type = VIDEO_ENCODER_LVDS;
|
encoder_type = VIDEO_ENCODER_LVDS;
|
||||||
} else if (encoder_support
|
} else if (connector_flags
|
||||||
& ATOM_DEVICE_CRT_SUPPORT) {
|
& ATOM_DEVICE_CRT_SUPPORT) {
|
||||||
encoder_type = VIDEO_ENCODER_DAC;
|
encoder_type = VIDEO_ENCODER_DAC;
|
||||||
} else {
|
} else {
|
||||||
@@ -519,10 +517,10 @@ detect_connectors()
|
|||||||
case ENCODER_OBJECT_ID_HDMI_SI1930:
|
case ENCODER_OBJECT_ID_HDMI_SI1930:
|
||||||
case ENCODER_OBJECT_ID_TRAVIS:
|
case ENCODER_OBJECT_ID_TRAVIS:
|
||||||
case ENCODER_OBJECT_ID_NUTMEG:
|
case ENCODER_OBJECT_ID_NUTMEG:
|
||||||
if (encoder_support
|
if (connector_flags
|
||||||
& ATOM_DEVICE_LCD_SUPPORT) {
|
& ATOM_DEVICE_LCD_SUPPORT) {
|
||||||
encoder_type = VIDEO_ENCODER_LVDS;
|
encoder_type = VIDEO_ENCODER_LVDS;
|
||||||
} else if (encoder_support
|
} else if (connector_flags
|
||||||
& ATOM_DEVICE_CRT_SUPPORT) {
|
& ATOM_DEVICE_CRT_SUPPORT) {
|
||||||
encoder_type = VIDEO_ENCODER_DAC;
|
encoder_type = VIDEO_ENCODER_DAC;
|
||||||
} else {
|
} else {
|
||||||
@@ -550,6 +548,8 @@ detect_connectors()
|
|||||||
i, decode_encoder_name(encoder_type));
|
i, decode_encoder_name(encoder_type));
|
||||||
|
|
||||||
gConnector[connector_index]->valid = true;
|
gConnector[connector_index]->valid = true;
|
||||||
|
|
||||||
|
gConnector[connector_index]->connector_flags = connector_flags;
|
||||||
gConnector[connector_index]->connector_type = connector_type;
|
gConnector[connector_index]->connector_type = connector_type;
|
||||||
gConnector[connector_index]->connector_object_id
|
gConnector[connector_index]->connector_object_id
|
||||||
= connector_object_id;
|
= connector_object_id;
|
||||||
@@ -581,52 +581,35 @@ detect_displays()
|
|||||||
gDisplay[id]->found_ranges = false;
|
gDisplay[id]->found_ranges = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 index = 0;
|
uint32 displayIndex = 0;
|
||||||
|
for (uint32 id = 0; id < ATOM_MAX_SUPPORTED_DEVICE; id++) {
|
||||||
|
if (gConnector[id]->valid == false)
|
||||||
|
continue;
|
||||||
|
if (displayIndex >= MAX_DISPLAY)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Probe for DAC monitors connected
|
bool found = false;
|
||||||
for (uint32 id = 0; id < 2; id++) {
|
switch(gConnector[id]->encoder_type) {
|
||||||
if (DACSense(id)) {
|
case VIDEO_ENCODER_DAC:
|
||||||
gDisplay[index]->active = true;
|
found = dac_sense(id);
|
||||||
gDisplay[index]->connection_type = ATOM_ENCODER_MODE_CRT;
|
break;
|
||||||
gDisplay[index]->connection_id = id;
|
default:
|
||||||
init_registers(gDisplay[index]->regs, index);
|
found = false;
|
||||||
if (detect_crt_ranges(index) == B_OK)
|
|
||||||
gDisplay[index]->found_ranges = true;
|
|
||||||
|
|
||||||
if (index < MAX_DISPLAY)
|
|
||||||
index++;
|
|
||||||
else
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Probe for TMDS monitors connected
|
if (found == true) {
|
||||||
for (uint32 id = 0; id < 1; id++) {
|
gDisplay[displayIndex]->active = true;
|
||||||
if (TMDSSense(id)) {
|
// set this display as active
|
||||||
gDisplay[index]->active = true;
|
gDisplay[displayIndex]->connector_index = id;
|
||||||
gDisplay[index]->connection_type = ATOM_ENCODER_MODE_DVI;
|
// set physical connector index from gConnector
|
||||||
// or ATOM_ENCODER_MODE_HDMI?
|
init_registers(gDisplay[displayIndex]->regs, displayIndex);
|
||||||
gDisplay[index]->connection_id = id;
|
|
||||||
init_registers(gDisplay[index]->regs, index);
|
|
||||||
if (detect_crt_ranges(index) == B_OK)
|
|
||||||
gDisplay[index]->found_ranges = true;
|
|
||||||
|
|
||||||
if (index < MAX_DISPLAY)
|
if (detect_crt_ranges(displayIndex) == B_OK)
|
||||||
index++;
|
gDisplay[displayIndex]->found_ranges = true;
|
||||||
else
|
displayIndex++;
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No monitors? Lets assume LVDS for now
|
|
||||||
if (index == 0) {
|
|
||||||
gDisplay[index]->active = true;
|
|
||||||
gDisplay[index]->connection_type = ATOM_ENCODER_MODE_LVDS;
|
|
||||||
gDisplay[index]->connection_id = 1;
|
|
||||||
// 0 : LVDSA ; 1 : LVDSB / TDMSB
|
|
||||||
init_registers(gDisplay[index]->regs, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,44 +622,13 @@ debug_displays()
|
|||||||
TRACE("Display #%" B_PRIu32 " active = %s\n",
|
TRACE("Display #%" B_PRIu32 " active = %s\n",
|
||||||
id, gDisplay[id]->active ? "true" : "false");
|
id, gDisplay[id]->active ? "true" : "false");
|
||||||
|
|
||||||
if (gDisplay[id]->active) {
|
uint32 connector_index = gDisplay[id]->connector_index;
|
||||||
switch (gDisplay[id]->connection_type) {
|
|
||||||
case ATOM_ENCODER_MODE_DP:
|
|
||||||
TRACE(" + connection: DP\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_LVDS:
|
|
||||||
TRACE(" + connection: LVDS\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_DVI:
|
|
||||||
TRACE(" + connection: DVI\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_HDMI:
|
|
||||||
TRACE(" + connection: HDMI\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_SDVO:
|
|
||||||
TRACE(" + connection: SDVO\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_DP_AUDIO:
|
|
||||||
TRACE(" + connection: DP AUDIO\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_TV:
|
|
||||||
TRACE(" + connection: TV\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_CV:
|
|
||||||
TRACE(" + connection: CV\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_CRT:
|
|
||||||
TRACE(" + connection: CRT\n");
|
|
||||||
break;
|
|
||||||
case ATOM_ENCODER_MODE_DVO:
|
|
||||||
TRACE(" + connection: DVO\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
TRACE(" + connection: UNKNOWN\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE(" + connection index: % " B_PRIu8 "\n",
|
if (gDisplay[id]->active) {
|
||||||
gDisplay[id]->connection_id);
|
uint32 connector_type = gConnector[connector_index]->connector_type;
|
||||||
|
uint32 encoder_type = gConnector[connector_index]->encoder_type;
|
||||||
|
TRACE(" + connector: %s\n", decode_connector_name(connector_type));
|
||||||
|
TRACE(" + encoder: %s\n", decode_encoder_name(encoder_type));
|
||||||
|
|
||||||
TRACE(" + limits: Vert Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n",
|
TRACE(" + limits: Vert Min/Max: %" B_PRIu32 "/%" B_PRIu32"\n",
|
||||||
gDisplay[id]->vfreq_min, gDisplay[id]->vfreq_max);
|
gDisplay[id]->vfreq_min, gDisplay[id]->vfreq_max);
|
||||||
@@ -689,6 +641,50 @@ debug_displays()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
display_get_encoder_mode(uint32 connector_index)
|
||||||
|
{
|
||||||
|
uint32 connector_type = gConnector[connector_index]->connector_type;
|
||||||
|
switch (connector_type) {
|
||||||
|
case VIDEO_CONNECTOR_DVII:
|
||||||
|
case VIDEO_CONNECTOR_HDMIB: /* HDMI-B is DL-DVI; analog works fine */
|
||||||
|
// TODO : if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
|
||||||
|
// if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
|
||||||
|
// if (gConnector[connector_index]->use_digital)
|
||||||
|
// return ATOM_ENCODER_MODE_DVI;
|
||||||
|
// else
|
||||||
|
return ATOM_ENCODER_MODE_CRT;
|
||||||
|
break;
|
||||||
|
case VIDEO_CONNECTOR_DVID:
|
||||||
|
case VIDEO_CONNECTOR_HDMIA:
|
||||||
|
default:
|
||||||
|
// TODO : if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
|
||||||
|
// if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
|
||||||
|
return ATOM_ENCODER_MODE_DVI;
|
||||||
|
case VIDEO_CONNECTOR_LVDS:
|
||||||
|
return ATOM_ENCODER_MODE_LVDS;
|
||||||
|
case VIDEO_CONNECTOR_DP:
|
||||||
|
// dig_connector = radeon_connector->con_priv;
|
||||||
|
// if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
|
||||||
|
// || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
|
||||||
|
// return ATOM_ENCODER_MODE_DP;
|
||||||
|
// }
|
||||||
|
// TODO : if audio detected on edid and DCE4, ATOM_ENCODER_MODE_DVI
|
||||||
|
// if audio detected on edid not DCE4, ATOM_ENCODER_MODE_HDMI
|
||||||
|
return ATOM_ENCODER_MODE_DVI;
|
||||||
|
case VIDEO_CONNECTOR_EDP:
|
||||||
|
return ATOM_ENCODER_MODE_DP;
|
||||||
|
case VIDEO_CONNECTOR_DVIA:
|
||||||
|
case VIDEO_CONNECTOR_VGA:
|
||||||
|
return ATOM_ENCODER_MODE_CRT;
|
||||||
|
case VIDEO_CONNECTOR_COMPOSITE:
|
||||||
|
case VIDEO_CONNECTOR_SVIDEO:
|
||||||
|
case VIDEO_CONNECTOR_9DIN:
|
||||||
|
return ATOM_ENCODER_MODE_TV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
display_crtc_lock(uint8 crtc_id, int command)
|
display_crtc_lock(uint8 crtc_id, int command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ status_t detect_crt_ranges(uint32 crtid);
|
|||||||
status_t detect_displays();
|
status_t detect_displays();
|
||||||
void debug_displays();
|
void debug_displays();
|
||||||
|
|
||||||
|
uint32 display_get_encoder_mode(uint32 connector_index);
|
||||||
void display_crtc_lock(uint8 crtc_id, int command);
|
void display_crtc_lock(uint8 crtc_id, int command);
|
||||||
void display_crtc_blank(uint8 crtc_id, int command);
|
void display_crtc_blank(uint8 crtc_id, int command);
|
||||||
void display_crtc_scale(uint8 crtc_id, display_mode *mode);
|
void display_crtc_scale(uint8 crtc_id, display_mode *mode);
|
||||||
|
|||||||
@@ -109,8 +109,13 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pll_set(gDisplay[id]->connection_id,
|
uint32 connector_index = gDisplay[id]->connector_index;
|
||||||
mode->timing.pixel_clock, id);
|
// uint32 connector_type = gConnector[connector_index]->connector_type;
|
||||||
|
uint32 encoder_type = gConnector[connector_index]->encoder_type;
|
||||||
|
|
||||||
|
// TODO : the first id is the pll we use... this won't work for
|
||||||
|
// more then two monitors
|
||||||
|
pll_set(id, mode->timing.pixel_clock, id);
|
||||||
|
|
||||||
// Program CRT Controller
|
// Program CRT Controller
|
||||||
display_crtc_set_dtd(id, mode);
|
display_crtc_set_dtd(id, mode);
|
||||||
@@ -119,16 +124,16 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
display_crtc_scale(id, mode);
|
display_crtc_scale(id, mode);
|
||||||
|
|
||||||
// Program connector controllers
|
// Program connector controllers
|
||||||
switch (gDisplay[id]->connection_type) {
|
switch (encoder_type) {
|
||||||
case ATOM_ENCODER_MODE_CRT:
|
case VIDEO_ENCODER_DAC:
|
||||||
DACSet(gDisplay[id]->connection_id, id);
|
case VIDEO_ENCODER_TVDAC:
|
||||||
|
// DACSet(connector_index, id);
|
||||||
break;
|
break;
|
||||||
case ATOM_ENCODER_MODE_DVI:
|
case VIDEO_ENCODER_TMDS:
|
||||||
case ATOM_ENCODER_MODE_HDMI:
|
// TMDSSet(connector_index, mode);
|
||||||
TMDSSet(gDisplay[id]->connection_id, mode);
|
|
||||||
break;
|
break;
|
||||||
case ATOM_ENCODER_MODE_LVDS:
|
case VIDEO_ENCODER_LVDS:
|
||||||
LVDSSet(gDisplay[id]->connection_id, mode);
|
// LVDSSet(connector_index, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,17 +144,17 @@ radeon_set_display_mode(display_mode *mode)
|
|||||||
//PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
//PLLPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
||||||
|
|
||||||
// Power connector controllers
|
// Power connector controllers
|
||||||
switch (gDisplay[id]->connection_type) {
|
switch (encoder_type) {
|
||||||
case ATOM_ENCODER_MODE_CRT:
|
case VIDEO_ENCODER_DAC:
|
||||||
DACPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
case VIDEO_ENCODER_TVDAC:
|
||||||
|
// DACPower(connector_index, RHD_POWER_ON);
|
||||||
break;
|
break;
|
||||||
case ATOM_ENCODER_MODE_DVI:
|
case VIDEO_ENCODER_TMDS:
|
||||||
case ATOM_ENCODER_MODE_HDMI:
|
// TMDSPower(connector_index, RHD_POWER_ON);
|
||||||
TMDSPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
|
||||||
break;
|
break;
|
||||||
case ATOM_ENCODER_MODE_LVDS:
|
case VIDEO_ENCODER_LVDS:
|
||||||
LVDSSet(gDisplay[id]->connection_id, mode);
|
// LVDSSet(connector_index, mode);
|
||||||
LVDSPower(gDisplay[id]->connection_id, RHD_POWER_ON);
|
// LVDSPower(connector_index, RHD_POWER_ON);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "accelerant_protos.h"
|
#include "accelerant_protos.h"
|
||||||
#include "accelerant.h"
|
#include "accelerant.h"
|
||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
|
#include "display.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "pll.h"
|
#include "pll.h"
|
||||||
|
|
||||||
@@ -187,6 +188,8 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
|||||||
uint8 crev;
|
uint8 crev;
|
||||||
atom_parse_cmd_header(gAtomContext, index, &frev, &crev);
|
atom_parse_cmd_header(gAtomContext, index, &frev, &crev);
|
||||||
|
|
||||||
|
uint32 connector_index = gDisplay[crtc_id]->connector_index;
|
||||||
|
|
||||||
switch (crev) {
|
switch (crev) {
|
||||||
case 1:
|
case 1:
|
||||||
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
|
args.v1.usPixelClock = B_HOST_TO_LENDIAN_INT16(pixelClock / 10);
|
||||||
@@ -220,7 +223,7 @@ pll_set(uint8 pll_id, uint32 pixelClock, uint8 crtc_id)
|
|||||||
// args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
|
// args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
|
||||||
args.v3.ucTransmitterId = crtc_id;
|
args.v3.ucTransmitterId = crtc_id;
|
||||||
// TODO : transmitter id is now CRTC id?
|
// TODO : transmitter id is now CRTC id?
|
||||||
args.v3.ucEncoderMode = gDisplay[crtc_id]->connection_type;
|
args.v3.ucEncoderMode = display_get_encoder_mode(connector_index);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
TRACE("%s: ERROR: table version %d.%d TODO\n", __func__,
|
TRACE("%s: ERROR: table version %d.%d TODO\n", __func__,
|
||||||
|
|||||||
Reference in New Issue
Block a user