From 0c52b2881758651f816064b284ef2a3c6fa662b5 Mon Sep 17 00:00:00 2001 From: Elmar Stellnberger Date: Sun, 7 Feb 2016 13:59:52 +0100 Subject: [PATCH] tried to introduce a radeon.hdmimhz and radeon.hdmikhz kernel module parameter --- drivers/gpu/drm/radeon/radeon.h | 2 + drivers/gpu/drm/radeon/radeon_connectors.c | 70 +++++++++++++++++++++++++++--- drivers/gpu/drm/radeon/radeon_drv.c | 8 ++++ 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5ae6db9..1ec5a82 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -113,6 +113,8 @@ extern int radeon_bapm; extern int radeon_backlight; extern int radeon_auxch; extern int radeon_mst; +extern int radeon_hdmimhz; +extern int radeon_hdmikhz; /* * 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..0fca613 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -29,6 +29,7 @@ #include #include #include +//#include #include "radeon.h" #include "radeon_audio.h" #include "atom.h" @@ -131,6 +132,11 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) int bpc = 8; int mode_clock, max_tmds_clock; + //struct stack_trace trace; + //DRM_DEBUG("backtrace\n"); + //save_stack_trace(&trace); + //print_stack_trace(&trace,2); + switch (connector->connector_type) { case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_HDMIB: @@ -204,8 +210,17 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) /* Maximum allowable input clock in kHz */ max_tmds_clock = connector->max_tmds_clock * 1000; - DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n", - connector->name, mode_clock, max_tmds_clock); + if(radeon_hdmimhz > 0 && max_tmds_clock < radeon_hdmimhz * 1000) + max_tmds_clock = radeon_hdmimhz * 1000; + + if(radeon_hdmikhz > 0 && max_tmds_clock < radeon_hdmikhz) + max_tmds_clock = radeon_hdmikhz; + + if(radeon_hdmikhz > 0 && mode_clock < radeon_hdmikhz) + mode_clock = radeon_hdmikhz; + + DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz (radeon.hdmimhz=%d/hdmikhz=%d).\n", + connector->name, mode_clock, max_tmds_clock, radeon_hdmimhz, radeon_hdmikhz); /* Check if bpc is within clock limit. Try to degrade gracefully otherwise */ if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) { @@ -393,6 +408,7 @@ static int radeon_ddc_get_modes(struct drm_connector *connector) return 0; } + static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) { int enc_id = connector->encoder_ids[0]; @@ -402,6 +418,26 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn return NULL; } + +static struct drm_encoder *radeon_best_single_encoder2(struct drm_connector *connector) +{ + struct drm_encoder *best_encoder, *encoder; struct radeon_encoder *radeon_encoder; int best_clock; + int idx, enc_id; + best_encoder = NULL; best_clock = 0; + for( idx=0; idx < DRM_CONNECTOR_MAX_ENCODER && (enc_id = connector->encoder_ids[idx]); idx++ ) { + encoder = drm_encoder_find(connector->dev, enc_id); + radeon_encoder = to_radeon_encoder(encoder); + if( best_encoder==NULL || best_clock < radeon_encoder->pixel_clock ) { + DRM_DEBUG("mhz; better clocking for %s: %d\n", encoder->name, radeon_encoder->pixel_clock); + best_encoder = encoder; + best_clock = radeon_encoder->pixel_clock; + } + + } + DRM_DEBUG("mhz; best clocking was found with %d.",best_clock); + return best_encoder; +} + static void radeon_get_native_mode(struct drm_connector *connector) { struct drm_encoder *encoder = radeon_best_single_encoder(connector); @@ -561,6 +597,8 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn } } +int radeon_debug_csp = 0; + static int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { @@ -573,6 +611,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct struct radeon_encoder_atom_dig *dig; bool new_coherent_mode; + if(radeon_debug_csp) DRM_DEBUG("mhz: coherent mode\n"); /* need to find digital encoder on connector */ encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) @@ -594,6 +633,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == rdev->mode_info.audio_property) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); /* need to find digital encoder on connector */ + if(radeon_debug_csp) DRM_DEBUG("mhz: audio\n"); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) return 0; @@ -608,6 +648,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == rdev->mode_info.dither_property) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); + if(radeon_debug_csp) DRM_DEBUG("mhz: dither\n"); /* need to find digital encoder on connector */ encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) @@ -623,6 +664,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == rdev->mode_info.underscan_property) { /* need to find digital encoder on connector */ + if(radeon_debug_csp) DRM_DEBUG("mhz: underscan\n"); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) return 0; @@ -637,6 +679,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == rdev->mode_info.underscan_hborder_property) { /* need to find digital encoder on connector */ + if(radeon_debug_csp) DRM_DEBUG("mhz: underscan_hborder\n"); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) return 0; @@ -651,6 +694,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == rdev->mode_info.underscan_vborder_property) { /* need to find digital encoder on connector */ + if(radeon_debug_csp) DRM_DEBUG("mhz: underscan_vborder\n"); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) return 0; @@ -691,6 +735,8 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct struct radeon_connector *radeon_connector = to_radeon_connector(connector); + if(radeon_debug_csp) DRM_DEBUG("mhz: load/detect\n"); + if (val == 0) radeon_connector->dac_load_detect = false; else @@ -701,6 +747,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct struct radeon_encoder_int_tmds *tmds = NULL; bool ret = false; /* need to find digital encoder on connector */ + if(radeon_debug_csp) DRM_DEBUG("mhz: tmds pll\n"); encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); if (!encoder) return 0; @@ -726,6 +773,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct if (property == dev->mode_config.scaling_mode_property) { enum radeon_rmx_type rmx_type; + if(radeon_debug_csp) DRM_DEBUG("mhz: scaling\n"); if (connector->encoder) radeon_encoder = to_radeon_encoder(connector->encoder); else { @@ -753,6 +801,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct } if (property == rdev->mode_info.output_csc_property) { + if(radeon_debug_csp) DRM_DEBUG("mhz: output csc\n"); if (connector->encoder) radeon_encoder = to_radeon_encoder(connector->encoder); else { @@ -1470,6 +1519,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 +1527,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 the modeclock for RV100 as it has a known issue with overclocking if (radeon_connector->use_digital && (mode->clock > 165000)) { if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || @@ -1487,19 +1537,25 @@ 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; } } /* check against the max pixel clock */ if ((mode->clock / 10) > rdev->clock.max_pixel_clock) - return MODE_CLOCK_HIGH; + mode_valid = MODE_CLOCK_HIGH; - return MODE_OK; + if(radeon_hdmimhz > 0 && (mode->clock <= radeon_hdmimhz * 1000)) + mode_valid = MODE_OK; + + if(radeon_hdmikhz > 0 && (mode->clock <= radeon_hdmikhz)) + mode_valid = 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..d39e059 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -194,6 +194,8 @@ int radeon_bapm = -1; int radeon_backlight = -1; int radeon_auxch = -1; int radeon_mst = 0; +int radeon_hdmimhz = 0; +int radeon_hdmikhz = 0; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -285,6 +287,12 @@ 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); + +MODULE_PARM_DESC(hdmikhz, "Force a certain HDMI pixel clock (in KHz) overriding hdmimhz; try f.i. 164250 / 266579 / 300000."); +module_param_named(hdmikhz, radeon_hdmikhz, int, 0400); + static struct pci_device_id pciidlist[] = { radeon_PCI_IDS }; -- 2.7.0