diff --git a/configure.ac b/configure.ac index 5dbf65a..461e3e3 100644 --- a/configure.ac +++ b/configure.ac @@ -233,6 +233,11 @@ AC_CHECK_DECL(XSERVER_LIBPCIACCESS, [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no], [#include "xorg-server.h"]) +AC_CHECK_DECL(xf86MonitorIsHDMI, + [AC_DEFINE(HAVE_DDC_HDMI_HELPER, 1, [Have xf86MonitorIsHDMI DDC helper])], + [], + [#include ]) + AC_CHECK_HEADERS([list.h], [], [], [#include diff --git a/src/atombios_output.c b/src/atombios_output.c index a028be0..324cf77 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -406,17 +406,21 @@ atombios_output_digital_setup(xf86OutputPtr output, int action) } static int -atombios_maybe_hdmi_mode(xf86OutputPtr output) +atombios_maybe_hdmi_mode(xf86OutputPtr output, ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output) { -#ifndef EDID_COMPLETE_RAWDATA - /* there's no getting this right unless we have complete EDID */ - return ATOM_ENCODER_MODE_HDMI; -#else - if (output && xf86MonitorIsHDMI(output->MonInfo)) - return ATOM_ENCODER_MODE_HDMI; + if (output) { + if (radeon_output->dp_fallback_adapter >= 0) + return radeon_output->dp_fallback_adapter; - return ATOM_ENCODER_MODE_DVI; +#ifdef HAVE_DDC_HDMI_HELPER + if (xf86MonitorIsHDMI(output->MonInfo)) { + xf86DrvMsg(pScrn->scrnIndex, X_NONE, "Detected adapter: HDMI\n"); + return ATOM_ENCODER_MODE_HDMI; #endif + } + + xf86DrvMsg(pScrn->scrnIndex, X_NONE, "Default adapter: DVI\n"); + return ATOM_ENCODER_MODE_DVI; } int @@ -443,7 +447,7 @@ atombios_get_encoder_mode(xf86OutputPtr output) if (IS_DCE4_VARIANT) return ATOM_ENCODER_MODE_DVI; else - return atombios_maybe_hdmi_mode(output); + return atombios_maybe_hdmi_mode(output, pScrn, radeon_output); break; case CONNECTOR_LVDS: return ATOM_ENCODER_MODE_LVDS; @@ -456,7 +460,7 @@ atombios_get_encoder_mode(xf86OutputPtr output) if (IS_DCE4_VARIANT) return ATOM_ENCODER_MODE_DVI; else - return atombios_maybe_hdmi_mode(output); + return atombios_maybe_hdmi_mode(output, pScrn, radeon_output); } break; case CONNECTOR_DVI_A: diff --git a/src/radeon.h b/src/radeon.h index 21c6d1c..1d53542 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -41,7 +41,10 @@ #include /* For usleep() */ #include /* For gettimeofday() */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include "xf86str.h" #include "compiler.h" #include "xf86fbman.h" @@ -224,7 +227,8 @@ typedef enum { OPTION_FORCE_LOW_POWER, OPTION_DYNAMIC_PM, OPTION_NEW_PLL, - OPTION_ZAPHOD_HEADS + OPTION_ZAPHOD_HEADS, + OPTION_DP_FALLBACK_ADAPTER, } RADEONOpts; diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 9e72c2d..cd0a2c3 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -206,6 +206,7 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_DYNAMIC_PM, "DynamicPM", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NEW_PLL, "NewPLL", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ZAPHOD_HEADS, "ZaphodHeads", OPTV_STRING, {0}, FALSE }, + { OPTION_DP_FALLBACK_ADAPTER, "DPFallbackAdapter", OPTV_STRING, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; diff --git a/src/radeon_output.c b/src/radeon_output.c index 689a592..4cfac03 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -157,6 +157,10 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn) if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id]); ErrorF(" DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg); + if (radeon_output->dp_fallback_adapter >= 0) + ErrorF(" Adapter: %s (configured)\n", (radeon_output->dp_fallback_adapter == ATOM_ENCODER_MODE_DVI) ? "DVI" : "HDMI"); + else + ErrorF(" Adapter: (auto)\n"); } } @@ -2865,6 +2869,20 @@ RADEONOutputCreate(ScrnInfoPtr pScrn, const char *name, int i) return xf86OutputCreate(pScrn, &radeon_output_funcs, buf); } +static void +RADEONSetDPFallbackAdapter(RADEONOutputPrivatePtr radeon_output, char **last) +{ + char *adapter_type = strtok_r(NULL, ",", last); + if (adapter_type) { + if (strcmp(adapter_type, "HDMI") == 0) { + radeon_output->dp_fallback_adapter = ATOM_ENCODER_MODE_HDMI; + } + else if (strcmp(adapter_type, "DVI") == 0) { + radeon_output->dp_fallback_adapter = ATOM_ENCODER_MODE_DVI; + } + } +} + /* * initialise the static data sos we don't have to re-do at randr change */ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) @@ -2872,7 +2890,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); xf86OutputPtr output; - char *optstr; + char *optstr, *dupstr = NULL, *last; int i; int num_vga = 0; int num_dvi = 0; @@ -3033,6 +3051,12 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } } + optstr = (char *)xf86GetOptValString(info->Options, OPTION_DP_FALLBACK_ADAPTER); + if (optstr) { + dupstr = strdup(optstr); + optstr = strtok_r(dupstr, ",", &last); + } + for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) { if (info->BiosConnector[i].valid) { RADEONOutputPrivatePtr radeon_output; @@ -3043,6 +3067,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1); if (!radeon_output) { + if (dupstr) + free(dupstr); return FALSE; } radeon_output->MonType = MT_UNKNOWN; @@ -3058,6 +3084,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) radeon_output->connector_object_id = info->BiosConnector[i].connector_object_id; radeon_output->ucI2cId = info->BiosConnector[i].ucI2cId; radeon_output->hpd_id = info->BiosConnector[i].hpd_id; + radeon_output->dp_fallback_adapter = -1; /* Technically HDMI-B is a glorfied DL DVI so the bios is correct, * but this can be confusing to users when it comes to output names, @@ -3072,16 +3099,21 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) output = RADEONOutputCreate(pScrn, "VGA-%d", --num_vga); } else if (conntype == CONNECTOR_HDMI_TYPE_A) { output = RADEONOutputCreate(pScrn, "HDMI-%d", --num_hdmi); + RADEONSetDPFallbackAdapter(radeon_output, &last); } else if (conntype == CONNECTOR_DISPLAY_PORT) { output = RADEONOutputCreate(pScrn, "DisplayPort-%d", --num_dp); + RADEONSetDPFallbackAdapter(radeon_output, &last); } else if (conntype == CONNECTOR_EDP) { output = RADEONOutputCreate(pScrn, "eDP-%d", --num_edp); + RADEONSetDPFallbackAdapter(radeon_output, &last); } else { output = RADEONOutputCreate(pScrn, ConnectorTypeName[conntype], 0); } if (!output) { + if (dupstr) + free(dupstr); return FALSE; } output->interlaceAllowed = TRUE; @@ -3104,6 +3136,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) } } + if (dupstr) + free(dupstr); + for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 36c91b2..41f65c3 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -307,6 +307,8 @@ typedef struct _RADEONOutputPrivateRec { int dp_clock; uint8_t hpd_id; int pll_id; + + int dp_fallback_adapter; } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr; struct avivo_pll_state {