From ca308c0b4227dc008c7951af5f7b52605ae1ecea Mon Sep 17 00:00:00 2001 From: Elmar Stellnberger Date: Thu, 3 Mar 2016 14:06:47 +0100 Subject: [PATCH] radeon.hdmimhz parameter introduced * proven to work for a radeon XFX R5 230 card with radeon.hdmimhz=297 3840x2160@30 is offered automatically and can be set successfully with an AOC u2868pqu monitor apparently without heat issues (cooler moderately warm after running half a day) * radeon_encoders.c: radeon_dig_monitor_is_duallink must always return false otherwise screen stays black for the settings described above --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_connectors.c | 16 ++++++++++------ drivers/gpu/drm/radeon/radeon_drv.c | 5 +++++ drivers/gpu/drm/radeon/radeon_encoders.c | 11 +++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 78a51b3..2be51ef 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -113,6 +113,7 @@ extern int radeon_bapm; extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; +extern int radeon_hdmimhz; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 340f3f5..d2a9bd8 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1470,6 +1470,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, struct drm_device *dev = connector->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_connector *radeon_connector = to_radeon_connector(connector); + int mode_valid = MODE_OK; /* XXX check mode bandwidth */ @@ -1477,7 +1478,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, if (radeon_connector->use_digital && (rdev->family == CHIP_RV100) && (mode->clock > 135000)) - return MODE_CLOCK_HIGH; + return MODE_CLOCK_HIGH; // never override since this is a known issue if (radeon_connector->use_digital && (mode->clock > 165000)) { if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || @@ -1487,19 +1488,22 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { /* HDMI 1.3+ supports max clock of 340 Mhz */ if (mode->clock > 340000) - return MODE_CLOCK_HIGH; + mode_valid = MODE_CLOCK_HIGH; else return MODE_OK; } else { - return MODE_CLOCK_HIGH; + mode_valid = MODE_CLOCK_HIGH; } } + if ( radeon_hdmimhz > 0 && ( mode->clock <= radeon_hdmimhz * 1000 ) ) + mode_valid = MODE_OK; + /* check against the max pixel clock */ - if ((mode->clock / 10) > rdev->clock.max_pixel_clock) - return MODE_CLOCK_HIGH; + if ( mode_valid == MODE_OK && (mode->clock / 10) > rdev->clock.max_pixel_clock) + mode_valid = MODE_CLOCK_HIGH; - return MODE_OK; + return mode_valid; } static const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index e266ffc..d77b026 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -194,6 +194,7 @@ int radeon_bapm = -1; int radeon_backlight = -1; int radeon_auxch = -1; int radeon_mst = 0; +int radeon_hdmimhz = 0; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -285,6 +286,10 @@ module_param_named(auxch, radeon_auxch, int, 0444); MODULE_PARM_DESC(mst, "DisplayPort MST experimental support (1 = enable, 0 = disable)"); module_param_named(mst, radeon_mst, int, 0444); +MODULE_PARM_DESC(hdmimhz, "Force a maximum HDMI pixel clock (in MHz); try 165/225/297/330 to overclock your TMDS for gaining a higher resolution."); +module_param_named(hdmimhz, radeon_hdmimhz, int, 0400); + + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index c6ee802..d89baf3 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -372,6 +372,9 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; + if ( radeon_hdmimhz > 0 ) + return false; + connector = radeon_get_connector_for_encoder(encoder); /* if we don't have an active device yet, just use one of * the connectors tied to the encoder. @@ -386,12 +389,12 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, if (radeon_connector->use_digital) { /* HDMI 1.3 supports up to 340 Mhz over single link */ if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { - if (pixel_clock > 340000) + if ( pixel_clock > 340000 ) return true; else return false; } else { - if (pixel_clock > 165000) + if ( pixel_clock > 165000 ) return true; else return false; @@ -411,12 +414,12 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, else { /* HDMI 1.3 supports up to 340 Mhz over single link */ if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) { - if (pixel_clock > 340000) + if ( pixel_clock > 340000 ) return true; else return false; } else { - if (pixel_clock > 165000) + if ( pixel_clock > 165000 ) return true; else return false; -- 2.7.2