From b8fb3d1705d9290842af96439080560891a8f6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 1 Mar 2007 09:35:22 +0000 Subject: [PATCH] Patch by Euan Kirkhope: Monitor Routing rework * mostly to fix my issues with dual monitors VGA + DVI which didn't work! ;) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20275 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../graphics/radeon/radeon_interface.h | 92 ++++++ headers/private/graphics/radeon/version.h | 2 +- .../accelerants/radeon/monitor_detection.c | 272 +++++++++++++++--- .../kernel/drivers/graphics/radeon/bios.c | 240 ++++++++++++++++ .../kernel/drivers/graphics/radeon/init.c | 1 + .../drivers/graphics/radeon/radeon_driver.h | 1 + 6 files changed, 566 insertions(+), 42 deletions(-) diff --git a/headers/private/graphics/radeon/radeon_interface.h b/headers/private/graphics/radeon/radeon_interface.h index a4dc01b59d..0d895a3bad 100644 --- a/headers/private/graphics/radeon/radeon_interface.h +++ b/headers/private/graphics/radeon/radeon_interface.h @@ -105,6 +105,97 @@ typedef enum { dd_dvi_ext = 64 // external DVI (only provided by few models) } display_device_e; +typedef enum +{ + ddc_none_detected, + ddc_monid, + ddc_dvi, + ddc_vga, + ddc_crt2 +} radeon_ddc_type; + +typedef enum +{ + mt_unknown = -1, + mt_none = 0, + mt_crt = 1, + mt_lcd = 2, + mt_dfp = 3, + mt_ctv = 4, + mt_stv = 5 +} radeon_monitor_type; + +typedef enum +{ + connector_none, + connector_proprietary, + connector_crt, + connector_dvi_i, + connector_dvi_d, + connector_ctv, + connector_stv, + connector_unsupported +} radeon_connector_type; + +typedef enum +{ + connector_none_atom, + connector_vga_atom, + connector_dvi_i_atom, + connector_dvi_d_atom, + connector_dvi_a_atom, + connector_stv_atom, + connector_ctv_atom, + connector_lvds_atom, + connector_digital_atom, + connector_unsupported_atom +} radeon_connector_type_atom; + +typedef enum +{ + dac_unknown = -1, + dac_primary = 0, + dac_tvdac = 1 +} radeon_dac_type; + +typedef enum +{ + tmds_unknown = -1, + tmds_int = 0, + tmds_ext = 1 +} radeon_tmds_type; + +typedef struct +{ + radeon_ddc_type ddc_type; + radeon_dac_type dac_type; + radeon_tmds_type tmds_type; + radeon_connector_type connector_type; + radeon_monitor_type mon_type; + edid1_info edid; + bool edid_valid; +} radeon_connector; + +typedef struct +{ + bool has_secondary; + + /* + * The next two are used to make sure CRTC2 is restored before CRTC_EXT, + * otherwise it could lead to blank screens. + */ + bool is_secondary_restored; + bool restore_primary; + + int mon_type1; + int mon_type2; + + bool reversed_DAC; /* TVDAC used as primary dac */ + bool reversed_TMDS; /* DDC_DVI is used for external TMDS */ + + radeon_connector port_info[2]; +} disp_entity, *ptr_disp_entity; + // type of ASIC typedef enum { @@ -448,6 +539,7 @@ typedef struct { uint8 num_crtc; // number of physical heads fp_info flatpanels[2]; // info about connected flat panels (if any) + disp_entity routing; // info if display connector routings eg DVI-I <- EXT TMDS <- DAC2 <- CRTC2 memory_type_info memory[mt_last]; // info about memory types memory_type_e nonlocal_type; // default type of non-local memory diff --git a/headers/private/graphics/radeon/version.h b/headers/private/graphics/radeon/version.h index 7283899b9a..2b0ce2bdb1 100644 --- a/headers/private/graphics/radeon/version.h +++ b/headers/private/graphics/radeon/version.h @@ -8,4 +8,4 @@ */ // current version -#define RADEON_DRIVER_VERSION "Version: 5.1.3.5" +#define RADEON_DRIVER_VERSION "Version: 5.1.4.0" diff --git a/src/add-ons/accelerants/radeon/monitor_detection.c b/src/add-ons/accelerants/radeon/monitor_detection.c index 6c4253275b..79c8405a16 100644 --- a/src/add-ons/accelerants/radeon/monitor_detection.c +++ b/src/add-ons/accelerants/radeon/monitor_detection.c @@ -834,59 +834,246 @@ static status_t Radeon_StoreFPEDID( accelerator_info *ai, const edid1_info *edid return B_OK; } +static void Radeon_ConnectorInfo( accelerator_info *ai, int port, disp_entity* ptr_entity ) +{ + const char* mon; + const char* ddc = ptr_entity->port_info[port].ddc_type == ddc_none_detected ? "None" : + ptr_entity->port_info[port].ddc_type == ddc_monid ? "Mon ID" : + ptr_entity->port_info[port].ddc_type == ddc_dvi ? "DVI DDC" : + ptr_entity->port_info[port].ddc_type == ddc_vga ? "VGA DDC" : + ptr_entity->port_info[port].ddc_type == ddc_crt2 ? "CRT2 DDC" : "Error"; + + const char* tmds = ptr_entity->port_info[port].tmds_type == tmds_unknown ? "None" : + ptr_entity->port_info[port].tmds_type == tmds_int ? "Internal" : + ptr_entity->port_info[port].tmds_type == tmds_ext ? "External" : "??? "; + + const char* dac = ptr_entity->port_info[port].dac_type == dac_unknown ? "Unknown" : + ptr_entity->port_info[port].dac_type == dac_primary ? "Primary" : + ptr_entity->port_info[port].dac_type == dac_tvdac ? "TV / External" : "Error"; + + const char* con; + if (ai->si->is_atombios) { + con = ptr_entity->port_info[port].connector_type == connector_none_atom ? "None" : + ptr_entity->port_info[port].connector_type == connector_vga_atom ? "VGA" : + ptr_entity->port_info[port].connector_type == connector_dvi_i_atom ? "DVI-I" : + ptr_entity->port_info[port].connector_type == connector_dvi_d_atom ? "DVI-D" : + ptr_entity->port_info[port].connector_type == connector_dvi_a_atom ? "DVI-A" : + ptr_entity->port_info[port].connector_type == connector_stv_atom ? "S-Video TV" : + ptr_entity->port_info[port].connector_type == connector_ctv_atom ? "Composite TV" : + ptr_entity->port_info[port].connector_type == connector_lvds_atom ? "LVDS" : + ptr_entity->port_info[port].connector_type == connector_digital_atom ? "Digital" : + ptr_entity->port_info[port].connector_type == connector_unsupported_atom ? "N/A " : "Err "; + } else { + con = ptr_entity->port_info[port].connector_type == connector_none ? "None" : + ptr_entity->port_info[port].connector_type == connector_crt ? "VGA" : + ptr_entity->port_info[port].connector_type == connector_dvi_i ? "DVI-I" : + ptr_entity->port_info[port].connector_type == connector_dvi_d ? "DVI-D" : + ptr_entity->port_info[port].connector_type == connector_proprietary ? "Proprietary" : + ptr_entity->port_info[port].connector_type == connector_stv ? "S-Video TV" : + ptr_entity->port_info[port].connector_type == connector_ctv ? "Composite TV" : + ptr_entity->port_info[port].connector_type == connector_unsupported ? "N/A" : "Err"; + } + + mon = ptr_entity->port_info[port].mon_type == mt_unknown ? "???" : + ptr_entity->port_info[port].mon_type == mt_none ? "None" : + ptr_entity->port_info[port].mon_type == mt_crt ? "CRT " : + ptr_entity->port_info[port].mon_type == mt_lcd ? "LCD " : + ptr_entity->port_info[port].mon_type == mt_dfp ? "DVI " : + ptr_entity->port_info[port].mon_type == mt_ctv ? "Composite TV" : + ptr_entity->port_info[port].mon_type == mt_stv ? "S-Video TV" : "Err ?"; + + SHOW_INFO( 2 , "Port %d:- \nMonitor: %s\nConn Type: %s\nDDC Port: %s\nTMDS Type: %s\nDAC Type: %s", + port, mon, con, ddc, tmds, dac); +} + // detect connected displays devices // whished_num_heads - how many heads the requested display mode needs void Radeon_DetectDisplays( accelerator_info *ai ) { shared_info *si = ai->si; + + disp_entity* routes = &si->routing; display_device_e displays = 0; display_device_e controlled_displays = ai->vc->controlled_displays; - edid1_info edid; + int i; + + uint32 edid_regs[] = { + 0, + RADEON_GPIO_MONID, + RADEON_GPIO_DVI_DDC, + RADEON_GPIO_VGA_DDC, + RADEON_GPIO_CRT2_DDC + }; // lock hardware so noone bothers us Radeon_WaitForIdle( ai, true ); - - // mobile chips are for use in laptops - there must be a laptop panel - if( si->is_mobility ) - displays |= dd_lvds; - - // use DDC to detect monitors - if we can read DDC, there must be a monitor - // all non-mobility versions have a DVI port - if( (displays & dd_lvds) == 0 && - Radeon_ReadEDID( ai, RADEON_GPIO_DVI_DDC, &edid )) - { - SHOW_FLOW0( 2, "Found monitor on DVI DDC port" ); - // there may be an analog monitor connected to DVI-I; - // we must check EDID to see whether it's really a digital monitor - if( edid.display.input_type == 1 ) { - SHOW_FLOW0( 2, "Must be a DVI monitor" ); - - // store info about DVI-connected flat-panel - if( Radeon_StoreFPEDID( ai, &edid ) == B_OK ) { - displays |= dd_dvi; - } else { - SHOW_ERROR0( 2, "Disabled DVI - invalid EDID" ); - } - } else { - // must be the analog portion of DVI - // I'm not sure about Radeons with one CRTC - do they have DVI-I or DVI-D? - // anyway - if there are two CRTC, analog portion must be connected - // to TV-DAC; if there is one CRTC, it must be the normal VGA-DAC - if( si->num_crtc > 1 ) { - SHOW_FLOW0( 2, "Must be an analog monitor on DVI port" ); - displays |= dd_tv_crt; - } else { - SHOW_FLOW0( 2, "Seems to be a CRT on VGA port!?" ); - displays |= dd_crt; - } + // alwats make TMDS_INT port first + if (routes->port_info[1].tmds_type == tmds_int) { + + radeon_connector swap_entity; + swap_entity = routes->port_info[0]; + routes->port_info[0] = routes->port_info[1]; + routes->port_info[1] = swap_entity; + SHOW_FLOW0( 2, "Swapping TMDS_INT to first port"); + } + else if ( routes->port_info[0].tmds_type != tmds_int && + routes->port_info[1].tmds_type != tmds_int ) { + + // no TMDS_INT port, make primary DAC port first + // On my Inspiron 8600 both internal and external ports are + // marked DAC_PRIMARY in BIOS. So be extra careful - only + // swap when the first port is not DAC_PRIMARY + if ( routes->port_info[1].dac_type == dac_primary && + routes->port_info[0].dac_type != dac_primary ) { + + radeon_connector swap_entity; + swap_entity = routes->port_info[0]; + routes->port_info[0] = routes->port_info[1]; + routes->port_info[1] = swap_entity; + SHOW_FLOW0( 2, "Swapping Primary Dac to front"); } } - // all chips have a standard VGA port - if( Radeon_ReadEDID( ai, RADEON_GPIO_VGA_DDC, &edid )) - displays |= dd_crt; + if ( si->asic == rt_rs300 ) // RS300 only has single Dac of TV type + { + // For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC + if ( routes->port_info[0].connector_type == connector_crt ) { + routes->port_info[0].dac_type = dac_tvdac; + routes->port_info[1].dac_type = dac_primary; + } else { + routes->port_info[1].dac_type = dac_primary; + routes->port_info[0].dac_type = dac_tvdac; + } + } else if ( si->num_crtc == 1 ) { + + routes->port_info[0].dac_type = dac_primary; + } + + // use DDC to detect monitors - if we can read DDC, there must be a monitor + for ( i = 0; i < 2; i++ ) + { + if (routes->port_info[i].mon_type != mt_unknown ) { + SHOW_FLOW0( 2, "known type, skpping detection" ); + continue; + } + + memset( &routes->port_info[i].edid , 0, sizeof(edid1_info) ); + switch ( routes->port_info[i].ddc_type ) { + case ddc_monid: + case ddc_dvi: + case ddc_vga: + case ddc_crt2: + if ( Radeon_ReadEDID( ai, edid_regs[routes->port_info[i].ddc_type], &routes->port_info[i].edid )) + { + routes->port_info[i].edid_valid = true; + SHOW_FLOW( 2, "Edid Data for CRTC %d on line %d", i, routes->port_info[i].ddc_type ); + edid_dump ( &routes->port_info[i].edid ); + } else { + routes->port_info[i].mon_type = mt_none; + } + + break; + default: + SHOW_FLOW( 2, "No Edid Pin Assigned to CRTC %d ", i ); + routes->port_info[i].mon_type = mt_none; + } + + if ( routes->port_info[i].edid_valid ) { + + if( routes->port_info[i].edid.display.input_type == 1 ) { + SHOW_FLOW0( 2, "Must be a DVI monitor" ); + + // Note some laptops have a DVI output that uses internal TMDS, + // when its DVI is enabled by hotkey, LVDS panel is not used. + // In this case, the laptop is configured as DVI+VGA as a normal + // desktop card. + // Also for laptop, when X starts with lid closed (no DVI connection) + // both LDVS and TMDS are disable, we still need to treat it as a LVDS panel. + if ( routes->port_info[i].tmds_type == tmds_ext ){ + // store info about DVI-connected flat-panel + if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) { + SHOW_INFO0( 2, "Found Ext Laptop DVI" ); + routes->port_info[i].mon_type = mt_dfp; + displays |= dd_dvi_ext; + } else { + SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" ); + } + } else { + if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) { + // store info about DVI-connected flat-panel + if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) { + SHOW_INFO0( 2, "Found DVI" ); + routes->port_info[i].mon_type = mt_dfp; + displays |= dd_dvi; + } else { + SHOW_ERROR0( 2, "Disabled DVI - invalid EDID" ); + } + } else { + SHOW_INFO0( 2, "Laptop Panel Found" ); + routes->port_info[i].mon_type = mt_lcd; + displays |= dd_lvds; + } + } + } else { + // must be the analog portion of DVI + // I'm not sure about Radeons with one CRTC - do they have DVI-I or DVI-D? + // anyway - if there are two CRTC, analog portion must be connected + // to TV-DAC; if there is one CRTC, it must be the normal VGA-DAC + if( si->num_crtc > 1 ) { + SHOW_FLOW0( 2, "Must be an analog monitor on DVI port" ); + routes->port_info[i].mon_type = mt_crt; + displays |= dd_tv_crt; + } else { + SHOW_FLOW0( 2, "Seems to be a CRT on VGA port!?" ); + routes->port_info[i].mon_type = mt_crt; + displays |= dd_crt; + } + } + } + } + + + if ( !routes->port_info[0].edid_valid ) { + SHOW_INFO0( 2, "Searching port 0" ); + if ( si->is_mobility && (INREG( ai->regs, RADEON_BIOS_4_SCRATCH) & 4)) { + SHOW_INFO0( 2, "Found Laptop Panel" ); + routes->port_info[0].mon_type = mt_lcd; + displays |= dd_lvds; + } + } + + if ( !routes->port_info[1].edid_valid ) { + + if ( si->is_mobility && (INREG( ai->regs, RADEON_FP2_GEN_CNTL) & RADEON_FP2_FPON)) { + SHOW_INFO0( 2, "Found Ext Laptop DVI" ); + routes->port_info[1].mon_type = mt_dfp; + displays |= dd_dvi; + } + } + + if ( routes->port_info[0].mon_type == mt_none ) + { + if ( routes->port_info[1].mon_type == mt_none ) { + routes->port_info[0].mon_type = mt_crt; + } else { + radeon_connector swap_entity; + swap_entity = routes->port_info[0]; + routes->port_info[0] = routes->port_info[1]; + routes->port_info[1] = swap_entity; + SHOW_ERROR0( 2, "swapping active port 2 to free port 1" ); + } + + } + + routes->reversed_DAC = false; + if ( routes->port_info[1].dac_type == dac_tvdac ) { + SHOW_ERROR0( 2, "Reversed dac detected (not impl. yet)" ); + routes->reversed_DAC = true; + } + + // we may have overseen monitors if they don't support DDC or // have broken DDC data (like mine); @@ -898,14 +1085,14 @@ void Radeon_DetectDisplays( accelerator_info *ai ) // all versions have a standard VGA port if( (displays & dd_crt) == 0 && - (controlled_displays && dd_crt) != 0 && + (controlled_displays & dd_crt) != 0 && Radeon_DetectCRT( ai )) displays |= dd_crt; // check VGA signal routed to DVI port // (the detection code checks whether there is hardware for that) if( (displays & dd_tv_crt) == 0 && - (controlled_displays && dd_tv_crt) != 0 && + (controlled_displays & dd_tv_crt) != 0 && Radeon_DetectTVCRT( ai )) displays |= dd_tv_crt; @@ -920,7 +1107,10 @@ void Radeon_DetectDisplays( accelerator_info *ai ) // if no monitor found, we define to have a CRT connected to CRT-DAC if( displays == 0 ) displays = dd_crt; - + + Radeon_ConnectorInfo( ai, 0, routes); + Radeon_ConnectorInfo( ai, 1, routes); + ai->vc->connected_displays = displays; RELEASE_BEN( si->cp.lock ); diff --git a/src/add-ons/kernel/drivers/graphics/radeon/bios.c b/src/add-ons/kernel/drivers/graphics/radeon/bios.c index 03d24d59a1..5e4d276012 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/bios.c +++ b/src/add-ons/kernel/drivers/graphics/radeon/bios.c @@ -259,6 +259,223 @@ static void Radeon_GetMonType( device_info *di ) } */ + +static bool Radeon_GetConnectorInfoFromBIOS ( device_info* di ) +{ + + ptr_disp_entity ptr_entity = &di->routing; + int i = 0, j, tmp, tmp0=0, tmp1=0; + + int bios_header, master_data_start; + + bios_header = RADEON_BIOS16(0x48); + + if (di->is_atombios) + { + master_data_start = RADEON_BIOS16( bios_header + 32 ); + tmp = RADEON_BIOS16( master_data_start + 22); + if (tmp) { + int crtc = 0, id[2]; + tmp1 = RADEON_BIOS16( tmp + 4 ); + for (i=0; i<8; i++) { + if(tmp1 & (1<> 8) & 0xf) == id[0] ) { + if (i == 3) + ptr_entity->port_info[0].tmds_type = tmds_int; + else if (i == 7) + ptr_entity->port_info[0].tmds_type = tmds_ext; + + if (ptr_entity->port_info[0].dac_type == dac_unknown) + ptr_entity->port_info[0].dac_type = (portinfo & 0xf) - 1; + continue; + } + } + + id[crtc] = (portinfo>>8) & 0xf; + ptr_entity->port_info[crtc].dac_type = (portinfo & 0xf) - 1; + ptr_entity->port_info[crtc].connector_type = (portinfo>>4) & 0xf; + if (i == 3) + ptr_entity->port_info[crtc].tmds_type = tmds_int; + else if (i == 7) + ptr_entity->port_info[crtc].tmds_type = tmds_ext; + + tmp0 = RADEON_BIOS16( master_data_start + 24); + if( tmp0 && id[crtc] ) { + switch (RADEON_BIOS16(tmp0 + 4 + 27 * id[crtc]) * 4) + { + case RADEON_GPIO_MONID: + ptr_entity->port_info[crtc].ddc_type = ddc_monid; + break; + case RADEON_GPIO_DVI_DDC: + ptr_entity->port_info[crtc].ddc_type = ddc_dvi; + break; + case RADEON_GPIO_VGA_DDC: + ptr_entity->port_info[crtc].ddc_type = ddc_vga; + break; + case RADEON_GPIO_CRT2_DDC: + ptr_entity->port_info[crtc].ddc_type = ddc_crt2; + break; + default: + ptr_entity->port_info[crtc].ddc_type = ddc_none_detected; + break; + } + + } else { + ptr_entity->port_info[crtc].ddc_type = ddc_none_detected; + } + crtc++; + } else { + /* we have already had two CRTCs assigned. the rest may share the same + * port with the existing connector, fill in them accordingly. + */ + for ( j = 0; j < 2; j++ ) { + if ((( portinfo >> 8 ) & 0xf ) == id[j] ) { + if ( i == 3 ) + ptr_entity->port_info[j].tmds_type = tmds_int; + else if (i == 7) + ptr_entity->port_info[j].tmds_type = tmds_ext; + + if ( ptr_entity->port_info[j].dac_type == dac_unknown ) + ptr_entity->port_info[j].dac_type = ( portinfo & 0xf ) - 1; + } + } + } + } + } + + for (i=0; i<2; i++) { + SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", + i, ptr_entity->port_info[i].ddc_type, ptr_entity->port_info[i].dac_type, + ptr_entity->port_info[i].tmds_type, ptr_entity->port_info[i].connector_type); + } + } else { + SHOW_INFO0( 4 , "No Device Info Table found!"); + return FALSE; + } + } else { + /* Some laptops only have one connector (VGA) listed in the connector table, + * we need to add LVDS in as a non-DDC display. + * Note, we can't assume the listed VGA will be filled in PortInfo[0], + * when walking through connector table. connector_found has following meaning: + * 0 -- nothing found, + * 1 -- only PortInfo[0] filled, + * 2 -- only PortInfo[1] filled, + * 3 -- both are filled. + */ + int connector_found = 0; + + if ((tmp = RADEON_BIOS16( bios_header + 0x50 ))) { + for ( i = 1; i < 4; i++ ) { + + if (!(RADEON_BIOS16( tmp + i * 2 ))) + break; /* end of table */ + + tmp0 = RADEON_BIOS16( tmp + i * 2 ); + if ((( tmp0 >> 12 ) & 0x0f ) == 0 ) + continue; /* no connector */ + if (connector_found > 0) { + if (ptr_entity->port_info[tmp1].ddc_type == (( tmp0 >> 8 ) & 0x0f )) + continue; /* same connector */ + } + + /* internal ddc_dvi port will get assigned to portinfo[0], or if there is no ddc_dvi (like in some igps). */ + tmp1 = (((( tmp0 >> 8 ) & 0xf ) == ddc_dvi ) || ( tmp1 == 1 )) ? 0 : 1; /* determine port info index */ + + ptr_entity->port_info[tmp1].ddc_type = (tmp0 >> 8) & 0x0f; + if (ptr_entity->port_info[tmp1].ddc_type > ddc_crt2) + ptr_entity->port_info[tmp1].ddc_type = ddc_none_detected; + ptr_entity->port_info[tmp1].dac_type = (tmp0 & 0x01) ? dac_tvdac : dac_primary; + ptr_entity->port_info[tmp1].connector_type = (tmp0 >> 12) & 0x0f; + if (ptr_entity->port_info[tmp1].connector_type > connector_unsupported) + ptr_entity->port_info[tmp1].connector_type = connector_unsupported; + ptr_entity->port_info[tmp1].tmds_type = ((tmp0 >> 4) & 0x01) ? tmds_ext : tmds_int; + + /* some sanity checks */ + if (((ptr_entity->port_info[tmp1].connector_type != connector_dvi_d) && + (ptr_entity->port_info[tmp1].connector_type != connector_dvi_i)) && + ptr_entity->port_info[tmp1].tmds_type == tmds_int) + ptr_entity->port_info[tmp1].tmds_type = tmds_unknown; + + connector_found += (tmp1 + 1); + } + } else { + SHOW_INFO0(4, "No Connector Info Table found!"); + return FALSE; + } + + if (di->is_mobility) + { + /* For the cases where only one VGA connector is found, + we assume LVDS is not listed in the connector table, + add it in here as the first port. + */ + if ((connector_found < 3) && (ptr_entity->port_info[tmp1].connector_type == connector_crt)) { + if (connector_found == 1) { + memcpy (&ptr_entity->port_info[1], + &ptr_entity->port_info[0], + sizeof (ptr_entity->port_info[0])); + } + ptr_entity->port_info[0].dac_type = dac_tvdac; + ptr_entity->port_info[0].tmds_type = tmds_unknown; + ptr_entity->port_info[0].ddc_type = ddc_none_detected; + ptr_entity->port_info[0].connector_type = connector_proprietary; + + SHOW_INFO0( 4 , "lvds port is not in connector table, added in."); + if (connector_found == 0) + connector_found = 1; + else + connector_found = 3; + } + + if ((tmp = RADEON_BIOS16( bios_header + 0x42 ))) { + if ((tmp0 = RADEON_BIOS16( tmp + 0x15 ))) { + if ((tmp1 = RADEON_BIOS16( tmp0 + 2 ) & 0x07)) { + ptr_entity->port_info[0].ddc_type = tmp1; + if (ptr_entity->port_info[0].ddc_type > ddc_crt2) { + SHOW_INFO( 4, "unknown ddctype %d found", + ptr_entity->port_info[0].ddc_type); + ptr_entity->port_info[0].ddc_type = ddc_none_detected; + } + SHOW_INFO0( 4, "lcd ddc info table found!"); + } + } + } + } else if (connector_found == 2) { + memcpy (&ptr_entity->port_info[0], + &ptr_entity->port_info[1], + sizeof (ptr_entity->port_info[0])); + ptr_entity->port_info[1].dac_type = dac_unknown; + ptr_entity->port_info[1].tmds_type = tmds_unknown; + ptr_entity->port_info[1].ddc_type = ddc_none_detected; + ptr_entity->port_info[1].connector_type = connector_none; + connector_found = 1; + } + + if (connector_found == 0) { + SHOW_INFO0( 4, "no connector found in connector info table."); + } else { + SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", + 0, ptr_entity->port_info[0].ddc_type, ptr_entity->port_info[0].dac_type, + ptr_entity->port_info[0].tmds_type, ptr_entity->port_info[0].connector_type); + + } + if (connector_found == 3) { + SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d", + 1, ptr_entity->port_info[1].ddc_type, ptr_entity->port_info[1].dac_type, + ptr_entity->port_info[1].tmds_type, ptr_entity->port_info[1].connector_type); + } + + } + return TRUE; +} + + // get flat panel info (does only make sense for Laptops // with integrated display, but looking for it doesn't hurt, // who knows which strange kind of combination is out there?) @@ -740,6 +957,29 @@ status_t Radeon_ReadBIOSData( device_info *di ) goto err1; Radeon_GetPLLInfo( di ); + + // setup defaults + di->routing.port_info[0].mon_type = mt_unknown; + di->routing.port_info[0].ddc_type = ddc_none_detected; + di->routing.port_info[0].dac_type = dac_unknown; + di->routing.port_info[0].tmds_type = tmds_unknown; + di->routing.port_info[0].connector_type = connector_none; + + if ( !Radeon_GetConnectorInfoFromBIOS( di ) ) + { + di->routing.port_info[0].mon_type = mt_unknown; + di->routing.port_info[0].ddc_type = ddc_none_detected; + di->routing.port_info[0].dac_type = dac_tvdac; + di->routing.port_info[0].tmds_type = tmds_unknown; + di->routing.port_info[0].connector_type = connector_proprietary; + + di->routing.port_info[1].mon_type = mt_unknown; + di->routing.port_info[1].ddc_type = ddc_none_detected; + di->routing.port_info[1].dac_type = dac_primary; + di->routing.port_info[1].tmds_type = tmds_ext; + di->routing.port_info[1].connector_type = connector_crt; + + } Radeon_GetFPData( di ); Radeon_DetectRAM( di ); diff --git a/src/add-ons/kernel/drivers/graphics/radeon/init.c b/src/add-ons/kernel/drivers/graphics/radeon/init.c index 439c9eb289..9d24a0c853 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/init.c +++ b/src/add-ons/kernel/drivers/graphics/radeon/init.c @@ -260,6 +260,7 @@ status_t Radeon_FirstOpen( device_info *di ) si->panel_pwr_delay = di->si->panel_pwr_delay; si->acc_dma = di->acc_dma; + memcpy(&si->routing, &di->routing, sizeof(disp_entity)); // detecting theatre channel in kernel would lead to code duplication, // so we let the first accelerant take care of it diff --git a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h index 3df4b11bd0..7bdae3a084 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h +++ b/src/add-ons/kernel/drivers/graphics/radeon/radeon_driver.h @@ -113,6 +113,7 @@ typedef struct device_info { bool acc_dma; fp_info fp_info; + disp_entity routing; general_pll_info pll; ram_info ram;