From 551402a30efa45560e23c22a7aa04453861602c3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Sep 2010 23:53:47 +0100 Subject: drm: Fix regression in disable polling e58f637 I broke out my trusty i845 and found a new boot failure, which upon inspection turned out to be a recursion within: drm_helper_probe_single_connector_modes() -> drm_helper_hpd_irq_event() -> intel_crt_detect() -> drm_helper_probe_single_connector_modes() Calling drm_kms_helper_poll_enable() instead performs the desired re-initialisation of the polling should the user have toggled the parameter, without the recursive side-effect. Signed-off-by: Chris Wilson Cc: Dave Airlie Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index d2ab01e90a9..4238a19c36d 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -104,7 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, connector->funcs->force(connector); } else { connector->status = connector->funcs->detect(connector); - drm_helper_hpd_irq_event(dev); + drm_kms_helper_poll_enable(dev); } if (connector->status == connector_status_disconnected) { -- cgit v1.2.3 From ff32a59daea4f3eae980ae8d0932b135c633ec5d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 7 Sep 2010 13:26:39 -0400 Subject: drm/radeon/kms: fix regression in RMX code (v2) caused by d65d65b175a29bd7ea2bb69c046419329c4a5db7 need to update the radeon crtc priv native mode before using it. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=30049 v2: integrate v/h copy paste typo Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 6dd434ad242..8c987c9923e 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1140,14 +1140,14 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, radeon_crtc->rmx_type = radeon_encoder->rmx_type; else radeon_crtc->rmx_type = RMX_OFF; - src_v = crtc->mode.vdisplay; - dst_v = radeon_crtc->native_mode.vdisplay; - src_h = crtc->mode.hdisplay; - dst_h = radeon_crtc->native_mode.vdisplay; /* copy native mode */ memcpy(&radeon_crtc->native_mode, &radeon_encoder->native_mode, sizeof(struct drm_display_mode)); + src_v = crtc->mode.vdisplay; + dst_v = radeon_crtc->native_mode.vdisplay; + src_h = crtc->mode.hdisplay; + dst_h = radeon_crtc->native_mode.hdisplay; /* fix up for overscan on hdmi */ if (ASIC_IS_AVIVO(rdev) && -- cgit v1.2.3 From aa74fbb4c905c6c746b79d4d7d8c95d8bbd4360c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 7 Sep 2010 14:41:30 -0400 Subject: drm/radeon/kms: add connector table for Mac x800 Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=28671 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_combios.c | 47 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 3 ++- 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index bd74e428bd1..a04b7a6ad95 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) /* PowerMac8,1 ? */ /* imac g5 isight */ rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; + } else if ((rdev->pdev->device == 0x4a48) && + (rdev->pdev->subsystem_vendor == 0x1002) && + (rdev->pdev->subsystem_device == 0x4a48)) { + /* Mac X800 */ + rdev->mode_info.connector_table = CT_MAC_X800; } else #endif /* CONFIG_PPC_PMAC */ #ifdef CONFIG_PPC64 @@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) CONNECTOR_OBJECT_ID_VGA, &hpd); break; + case CT_MAC_X800: + DRM_INFO("Connector Table: %d (mac x800)\n", + rdev->mode_info.connector_table); + /* DVI - primary dac, internal tmds */ + ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); + hpd.hpd = RADEON_HPD_1; /* ??? */ + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT); + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); + radeon_add_legacy_connector(dev, 0, + ATOM_DEVICE_DFP1_SUPPORT | + ATOM_DEVICE_CRT1_SUPPORT, + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, + &hpd); + /* DVI - tv dac, dvo */ + ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); + hpd.hpd = RADEON_HPD_2; /* ??? */ + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT); + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT); + radeon_add_legacy_connector(dev, 1, + ATOM_DEVICE_DFP2_SUPPORT | + ATOM_DEVICE_CRT2_SUPPORT, + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, + &hpd); + break; default: DRM_INFO("Connector table: %d (invalid)\n", rdev->mode_info.connector_table); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index efbe975312d..17a6602b588 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -204,7 +204,7 @@ struct radeon_i2c_chan { /* mostly for macs, but really any system without connector tables */ enum radeon_connector_table { - CT_NONE, + CT_NONE = 0, CT_GENERIC, CT_IBOOK, CT_POWERBOOK_EXTERNAL, @@ -215,6 +215,7 @@ enum radeon_connector_table { CT_IMAC_G5_ISIGHT, CT_EMAC, CT_RN50_POWER, + CT_MAC_X800, }; enum radeon_dvo_chip { -- cgit v1.2.3 From e6db0da02ea753968d15ae3e835059c207647e78 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 10 Sep 2010 03:19:05 -0400 Subject: drm/radeon/kms: don't enable underscan with interlaced modes They aren't compatible. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8c987c9923e..127a395f70f 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1151,6 +1151,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, /* fix up for overscan on hdmi */ if (ASIC_IS_AVIVO(rdev) && + (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && ((radeon_encoder->underscan_type == UNDERSCAN_ON) || ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && drm_detect_hdmi_monitor(radeon_connector->edid) && -- cgit v1.2.3 From 356ad3cd616185631235ffb48b3efbf39f9923b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 9 Sep 2010 09:41:32 +0100 Subject: drm: Only decouple the old_fb from the crtc is we call mode_set* Otherwise when disabling the output we switch to the new fb (which is likely NULL) and skip the call to mode_set -- leaking driver private state on the old_fb. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29857 Reported-by: Sitsofe Wheeler Signed-off-by: Chris Wilson Cc: Dave Airlie Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 4238a19c36d..de152a58967 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -637,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) mode_changed = true; if (mode_changed) { - old_fb = set->crtc->fb; - set->crtc->fb = set->fb; set->crtc->enabled = (set->mode != NULL); if (set->mode != NULL) { DRM_DEBUG_KMS("attempting to set mode from" " userspace\n"); drm_mode_debug_printmodeline(set->mode); + old_fb = set->crtc->fb; + set->crtc->fb = set->fb; if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) { -- cgit v1.2.3 From 27849044ca6ff9c52f63271b511282acf6d1c251 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Sep 2010 11:31:13 -0400 Subject: drm/radeon: add some missing copyright headers Noticed while adding evergreen blit support. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_blit_kms.c | 25 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/r600_blit_shaders.h | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d13622ae74e..9ceb2a1ce79 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -1,3 +1,28 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * Copyright 2009 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + #include "drmP.h" #include "drm.h" #include "radeon_drm.h" diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h index fdc3b378cbb..f437d36dd98 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.h +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h @@ -1,3 +1,27 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * Copyright 2009 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ #ifndef R600_BLIT_SHADERS_H #define R600_BLIT_SHADERS_H -- cgit v1.2.3 From 7b334fcb45b757ffb093696ca3de1b0c8b4a33f1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 9 Sep 2010 23:51:02 +0100 Subject: drm: Use a nondestructive mode for output detect when polling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Destructive load-detection is very expensive and due to failings elsewhere can trigger system wide stalls of up to 600ms. A simple first step to correcting this is not to invoke such an expensive and destructive load-detection operation automatically. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29536 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16265 Reported-by: Bruno Prémont Tested-by: Sitsofe Wheeler Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 4 ++-- drivers/gpu/drm/drm_sysfs.c | 2 +- drivers/gpu/drm/i915/intel_crt.c | 7 ++++++- drivers/gpu/drm/i915/intel_dp.c | 3 ++- drivers/gpu/drm/i915/intel_dvo.c | 4 +++- drivers/gpu/drm/i915/intel_hdmi.c | 3 ++- drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++-- drivers/gpu/drm/i915/intel_sdvo.c | 6 ++++-- drivers/gpu/drm/i915/intel_tv.c | 12 ++++++------ drivers/gpu/drm/nouveau/nouveau_connector.c | 8 +++++--- drivers/gpu/drm/radeon/radeon_connectors.c | 20 +++++++++++++++----- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 3 ++- include/drm/drm_crtc.h | 3 ++- 13 files changed, 56 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index de152a58967..fb6b70fc657 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -103,7 +103,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (connector->funcs->force) connector->funcs->force(connector); } else { - connector->status = connector->funcs->detect(connector); + connector->status = connector->funcs->detect(connector, false); drm_kms_helper_poll_enable(dev); } @@ -866,7 +866,7 @@ static void output_poll_execute(struct work_struct *work) !(connector->polled & DRM_CONNECTOR_POLL_HPD)) continue; - status = connector->funcs->detect(connector); + status = connector->funcs->detect(connector, true); if (old_status != status) changed = true; } diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 86118a74223..85da4c40694 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device, struct drm_connector *connector = to_drm_connector(device); enum drm_connector_status status; - status = connector->funcs->detect(connector); + status = connector->funcs->detect(connector, true); return snprintf(buf, PAGE_SIZE, "%s\n", drm_get_connector_status_name(status)); } diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4b7735196cd..0350e5d711f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -400,7 +400,9 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder return status; } -static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) +static enum drm_connector_status +intel_crt_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_device *dev = connector->dev; struct drm_encoder *encoder = intel_attached_encoder(connector); @@ -419,6 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto if (intel_crt_detect_ddc(encoder)) return connector_status_connected; + if (nondestructive) + return connector->status; + /* for pre-945g platforms use load detect */ if (encoder->crtc && encoder->crtc->enabled) { status = intel_crt_load_detect(encoder->crtc, intel_encoder); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 51d142939a2..e1a2a05fb83 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1386,7 +1386,8 @@ ironlake_dp_detect(struct drm_connector *connector) * \return false if DP port is disconnected. */ static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector) +intel_dp_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a399f4b2c1c..f0de1addf8a 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -221,7 +221,9 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, * * Unimplemented. */ -static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) +static enum drm_connector_status +intel_dvo_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index ccd4c97e652..2ea123d8d22 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -139,7 +139,8 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, } static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector) +intel_hdmi_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4fbb0165b26..fb1bed8f407 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -445,7 +445,9 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, * connected and closed means disconnected. We also send hotplug events as * needed, using lid status notification from the input layer. */ -static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) +static enum drm_connector_status +intel_lvds_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_device *dev = connector->dev; enum drm_connector_status status = connector_status_connected; @@ -540,7 +542,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, * the LID nofication event. */ if (connector) - connector->status = connector->funcs->detect(connector); + connector->status = connector->funcs->detect(connector, + true); + /* Don't force modeset on machines where it causes a GPU lockup */ if (dmi_check_system(intel_no_modeset_on_lid)) return NOTIFY_OK; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e3b7a7ee39c..db6b6d4b8fa 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) if (!analog_connector) return false; - if (analog_connector->funcs->detect(analog_connector) == + if (analog_connector->funcs->detect(analog_connector, true) == connector_status_disconnected) return false; @@ -1486,7 +1486,9 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) return status; } -static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) +static enum drm_connector_status +intel_sdvo_detect(struct drm_connector *connector, + bool nondestructive) { uint16_t response; struct drm_encoder *encoder = intel_attached_encoder(connector); diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index c671f60ce80..d20b550c0f5 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1341,7 +1341,8 @@ static void intel_tv_find_better_format(struct drm_connector *connector) * we have a pipe programmed in order to probe the TV. */ static enum drm_connector_status -intel_tv_detect(struct drm_connector *connector) +intel_tv_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_display_mode mode; struct drm_encoder *encoder = intel_attached_encoder(connector); @@ -1353,7 +1354,7 @@ intel_tv_detect(struct drm_connector *connector) if (encoder->crtc && encoder->crtc->enabled) { type = intel_tv_detect_type(intel_tv); - } else { + } else if (nondestructive) { struct drm_crtc *crtc; int dpms_mode; @@ -1364,10 +1365,9 @@ intel_tv_detect(struct drm_connector *connector) intel_release_load_detect_pipe(&intel_tv->base, connector, dpms_mode); } else - type = -1; - } - - intel_tv->type = type; + return connector_status_unknown; + } else + return connector->status; if (type < 0) return connector_status_disconnected; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a1473fff06a..67d515cb67e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -168,7 +168,8 @@ nouveau_connector_set_encoder(struct drm_connector *connector, } static enum drm_connector_status -nouveau_connector_detect(struct drm_connector *connector) +nouveau_connector_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_device *dev = connector->dev; struct nouveau_connector *nv_connector = nouveau_connector(connector); @@ -246,7 +247,8 @@ detect_analog: } static enum drm_connector_status -nouveau_connector_detect_lvds(struct drm_connector *connector) +nouveau_connector_detect_lvds(struct drm_connector *connector, + bool nondestructive) { struct drm_device *dev = connector->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -267,7 +269,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector) /* Try retrieving EDID via DDC */ if (!dev_priv->vbios.fp_no_ddc) { - status = nouveau_connector_detect(connector); + status = nouveau_connector_detect(connector, nondestructive); if (status == connector_status_connected) goto out; } diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index a9dd7847d96..31d309a8e75 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -481,7 +481,9 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, return MODE_OK; } -static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) +static enum drm_connector_status +radeon_lvds_detect(struct drm_connector *connector, + bool nondestructive) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); @@ -594,7 +596,9 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, return MODE_OK; } -static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) +static enum drm_connector_status +radeon_vga_detect(struct drm_connector *connector, + bool nondestructive) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder; @@ -691,7 +695,9 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, return MODE_OK; } -static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) +static enum drm_connector_status +radeon_tv_detect(struct drm_connector *connector, + bool nondestructive) { struct drm_encoder *encoder; struct drm_encoder_helper_funcs *encoder_funcs; @@ -748,7 +754,9 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) * we have to check if this analog encoder is shared with anyone else (TV) * if its shared we have to set the other connector to disconnected. */ -static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) +static enum drm_connector_status +radeon_dvi_detect(struct drm_connector *connector, + bool nondestructive) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = NULL; @@ -972,7 +980,9 @@ static int radeon_dp_get_modes(struct drm_connector *connector) return ret; } -static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) +static enum drm_connector_status +radeon_dp_detect(struct drm_connector *connector, + bool nondestructive) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); enum drm_connector_status ret = connector_status_disconnected; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 2ff5cf78235..a527c91c0ba 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) } static enum drm_connector_status - vmw_ldu_connector_detect(struct drm_connector *connector) + vmw_ldu_connector_detect(struct drm_connector *connector, + bool nondestructive) { if (vmw_connector_to_ldu(connector)->pref_active) return connector_status_connected; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c9f3cc5949a..5536223fbac 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -386,7 +386,8 @@ struct drm_connector_funcs { void (*dpms)(struct drm_connector *connector, int mode); void (*save)(struct drm_connector *connector); void (*restore)(struct drm_connector *connector); - enum drm_connector_status (*detect)(struct drm_connector *connector); + enum drm_connector_status (*detect)(struct drm_connector *connector, + bool nondestructive); int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); int (*set_property)(struct drm_connector *connector, struct drm_property *property, uint64_t val); -- cgit v1.2.3 From b741be82cf2079f71553af595610f17a3a3a752a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 9 Sep 2010 19:15:23 -0400 Subject: drm/radeon/kms/evergreen: fix backend setup This patch fixes rendering errors on some evergreen boards. Hardcoding the backend map is not an optimal solution, but a better fix is being worked on. Similar to the fix for rv740 (6271901d828b34b27607314026deaf417f9f9b75). Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=29986 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b8b7f010b25..79082d4398a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1160,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev) EVERGREEN_MAX_BACKENDS_MASK)); break; } - } else - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); + } else { + switch (rdev->family) { + case CHIP_CYPRESS: + case CHIP_HEMLOCK: + gb_backend_map = 0x66442200; + break; + case CHIP_JUNIPER: + gb_backend_map = 0x00006420; + break; + default: + gb_backend_map = + evergreen_get_tile_pipe_to_backend_map(rdev, + rdev->config.evergreen.max_tile_pipes, + rdev->config.evergreen.max_backends, + ((EVERGREEN_MAX_BACKENDS_MASK << + rdev->config.evergreen.max_backends) & + EVERGREEN_MAX_BACKENDS_MASK)); + } + } rdev->config.evergreen.tile_config = gb_addr_config; WREG32(GB_BACKEND_MAP, gb_backend_map); -- cgit v1.2.3 From ec00efb72f4b88078427d01f38f664c67c7ca0c0 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 12 Sep 2010 05:09:12 +0200 Subject: drm/radeon/kms: increase lockup detection interval to 10 sec for r100-r500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One subtest of mesa/demos/gltestperf takes 9 seconds to complete, so to prevent an unnecessary gpu reset followed by a hardlock, I am increasing the interval to 10 seconds after which a GPU is considered in a locked-up state. This is on RV530. However, with a little slower GPU, we would surpass the interval easily, so this is not a good fix for gltestperf. Nevertheless, this commit also fixes hardlocks in the applications which render at speed of less than 1 frame per second, where the whole frame consists of only one command stream. The game Tiny & Big is an example. This bar is now lowered to 0.1 fps. Now the question comes down to whether we should (often unsuccessfully) reset the GPU at all? Once we have stable enough drivers, we won't have to. Has the time come already? If possible, this commit should go to stable as well. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e817a0bb5eb..ec64b365ee1 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2020,18 +2020,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l return false; } elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); - if (elapsed >= 3000) { - /* very likely the improbable case where current - * rptr is equal to last recorded, a while ago, rptr - * this is more likely a false positive update tracking - * information which should force us to be recall at - * latter point - */ - lockup->last_cp_rptr = cp->rptr; - lockup->last_jiffies = jiffies; - return false; - } - if (elapsed >= 1000) { + if (elapsed >= 10000) { dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); return true; } -- cgit v1.2.3 From a41ceb1c17af06a17c0d88e987215ef20b93c471 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 12 Sep 2010 05:09:13 +0200 Subject: drm/radeon/kms: fix the colorbuffer CS checker for r300-r500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes bogus CS rejection if it contains a sequence of the following operations: - Set the color buffer 0. track->cb[i].robj becomes non-NULL. - Render. - Set a larger zbuffer than the previously-set color buffer. - Set a larger scissor area as well. - Set the color channel mask to 0 to do depth-only rendering. - Render. --> rejected, because track->cb[i].robj remained non-NULL, therefore the conditional checking for the color channel mask and friends is not performed, and the larger scissor area causes the rejection. This fixes bugs: - https://bugs.freedesktop.org/show_bug.cgi?id=29762 - https://bugs.freedesktop.org/show_bug.cgi?id=28869 And maybe some others which seem to look the same. If possible, this commit should go to stable as well. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index ec64b365ee1..e151f16a8f8 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3297,13 +3297,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) unsigned long size; unsigned prim_walk; unsigned nverts; + unsigned num_cb = track->num_cb; - for (i = 0; i < track->num_cb; i++) { + if (!track->zb_cb_clear && !track->color_channel_mask && + !track->blend_read_enable) + num_cb = 0; + + for (i = 0; i < num_cb; i++) { if (track->cb[i].robj == NULL) { - if (!(track->zb_cb_clear || track->color_channel_mask || - track->blend_read_enable)) { - continue; - } DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); return -EINVAL; } -- cgit v1.2.3 From 930a9e283516a3a3595c0c515113f1b78d07f695 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Sep 2010 11:07:23 +0100 Subject: drm: Use a nondestructive mode for output detect when polling (v2) v2: Julien Cristau pointed out that @nondestructive results in double-negatives and confusion when trying to interpret the parameter, so use @force instead. Much easier to type as well. ;-) And fix the miscompilation of vmgfx reported by Sedat Dilek. Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 4 ++-- drivers/gpu/drm/i915/intel_crt.c | 5 ++--- drivers/gpu/drm/i915/intel_dp.c | 3 +-- drivers/gpu/drm/i915/intel_dvo.c | 3 +-- drivers/gpu/drm/i915/intel_hdmi.c | 3 +-- drivers/gpu/drm/i915/intel_lvds.c | 5 ++--- drivers/gpu/drm/i915/intel_sdvo.c | 5 ++--- drivers/gpu/drm/i915/intel_tv.c | 5 ++--- drivers/gpu/drm/nouveau/nouveau_connector.c | 8 +++----- drivers/gpu/drm/radeon/radeon_connectors.c | 15 +++++---------- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 6 +++--- include/drm/drm_crtc.h | 9 ++++++++- 12 files changed, 32 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index fb6b70fc657..dcbeb98f195 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -103,7 +103,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (connector->funcs->force) connector->funcs->force(connector); } else { - connector->status = connector->funcs->detect(connector, false); + connector->status = connector->funcs->detect(connector, true); drm_kms_helper_poll_enable(dev); } @@ -866,7 +866,7 @@ static void output_poll_execute(struct work_struct *work) !(connector->polled & DRM_CONNECTOR_POLL_HPD)) continue; - status = connector->funcs->detect(connector, true); + status = connector->funcs->detect(connector, false); if (old_status != status) changed = true; } diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0350e5d711f..a02a8df7372 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -401,8 +401,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder } static enum drm_connector_status -intel_crt_detect(struct drm_connector *connector, - bool nondestructive) +intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct drm_encoder *encoder = intel_attached_encoder(connector); @@ -421,7 +420,7 @@ intel_crt_detect(struct drm_connector *connector, if (intel_crt_detect_ddc(encoder)) return connector_status_connected; - if (nondestructive) + if (!force) return connector->status; /* for pre-945g platforms use load detect */ diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e1a2a05fb83..1a51ee07de3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1386,8 +1386,7 @@ ironlake_dp_detect(struct drm_connector *connector) * \return false if DP port is disconnected. */ static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, - bool nondestructive) +intel_dp_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index f0de1addf8a..7c9ec1472d4 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -222,8 +222,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, * Unimplemented. */ static enum drm_connector_status -intel_dvo_detect(struct drm_connector *connector, - bool nondestructive) +intel_dvo_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2ea123d8d22..926934a482e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -139,8 +139,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, } static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, - bool nondestructive) +intel_hdmi_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index fb1bed8f407..6ec39a86ed0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -446,8 +446,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, * needed, using lid status notification from the input layer. */ static enum drm_connector_status -intel_lvds_detect(struct drm_connector *connector, - bool nondestructive) +intel_lvds_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; enum drm_connector_status status = connector_status_connected; @@ -543,7 +542,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, */ if (connector) connector->status = connector->funcs->detect(connector, - true); + false); /* Don't force modeset on machines where it causes a GPU lockup */ if (dmi_check_system(intel_no_modeset_on_lid)) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index db6b6d4b8fa..e8e902d614e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) if (!analog_connector) return false; - if (analog_connector->funcs->detect(analog_connector, true) == + if (analog_connector->funcs->detect(analog_connector, false) == connector_status_disconnected) return false; @@ -1487,8 +1487,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) } static enum drm_connector_status -intel_sdvo_detect(struct drm_connector *connector, - bool nondestructive) +intel_sdvo_detect(struct drm_connector *connector, bool force) { uint16_t response; struct drm_encoder *encoder = intel_attached_encoder(connector); diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d20b550c0f5..4a117e318a7 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1341,8 +1341,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector) * we have a pipe programmed in order to probe the TV. */ static enum drm_connector_status -intel_tv_detect(struct drm_connector *connector, - bool nondestructive) +intel_tv_detect(struct drm_connector *connector, bool force) { struct drm_display_mode mode; struct drm_encoder *encoder = intel_attached_encoder(connector); @@ -1354,7 +1353,7 @@ intel_tv_detect(struct drm_connector *connector, if (encoder->crtc && encoder->crtc->enabled) { type = intel_tv_detect_type(intel_tv); - } else if (nondestructive) { + } else if (force) { struct drm_crtc *crtc; int dpms_mode; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 67d515cb67e..87186a4bbf0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -168,8 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, } static enum drm_connector_status -nouveau_connector_detect(struct drm_connector *connector, - bool nondestructive) +nouveau_connector_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct nouveau_connector *nv_connector = nouveau_connector(connector); @@ -247,8 +246,7 @@ detect_analog: } static enum drm_connector_status -nouveau_connector_detect_lvds(struct drm_connector *connector, - bool nondestructive) +nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -269,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, /* Try retrieving EDID via DDC */ if (!dev_priv->vbios.fp_no_ddc) { - status = nouveau_connector_detect(connector, nondestructive); + status = nouveau_connector_detect(connector, force); if (status == connector_status_connected) goto out; } diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 31d309a8e75..ecc1a8fafbf 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -482,8 +482,7 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, } static enum drm_connector_status -radeon_lvds_detect(struct drm_connector *connector, - bool nondestructive) +radeon_lvds_detect(struct drm_connector *connector, bool force) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); @@ -597,8 +596,7 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, } static enum drm_connector_status -radeon_vga_detect(struct drm_connector *connector, - bool nondestructive) +radeon_vga_detect(struct drm_connector *connector, bool force) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder; @@ -696,8 +694,7 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, } static enum drm_connector_status -radeon_tv_detect(struct drm_connector *connector, - bool nondestructive) +radeon_tv_detect(struct drm_connector *connector, bool force) { struct drm_encoder *encoder; struct drm_encoder_helper_funcs *encoder_funcs; @@ -755,8 +752,7 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) * if its shared we have to set the other connector to disconnected. */ static enum drm_connector_status -radeon_dvi_detect(struct drm_connector *connector, - bool nondestructive) +radeon_dvi_detect(struct drm_connector *connector, bool force) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = NULL; @@ -981,8 +977,7 @@ static int radeon_dp_get_modes(struct drm_connector *connector) } static enum drm_connector_status -radeon_dp_detect(struct drm_connector *connector, - bool nondestructive) +radeon_dp_detect(struct drm_connector *connector, bool force) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); enum drm_connector_status ret = connector_status_disconnected; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a527c91c0ba..7083b1a24df 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -336,7 +336,7 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) static enum drm_connector_status vmw_ldu_connector_detect(struct drm_connector *connector, - bool nondestructive) + bool force) { if (vmw_connector_to_ldu(connector)->pref_active) return connector_status_connected; @@ -517,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - connector->status = vmw_ldu_connector_detect(connector); + connector->status = vmw_ldu_connector_detect(connector, true); drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, DRM_MODE_ENCODER_LVDS); @@ -611,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, ldu->pref_height = 600; ldu->pref_active = false; } - con->status = vmw_ldu_connector_detect(con); + con->status = vmw_ldu_connector_detect(con, true); } mutex_unlock(&dev->mode_config.mutex); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 5536223fbac..3e5a51af757 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -386,8 +386,15 @@ struct drm_connector_funcs { void (*dpms)(struct drm_connector *connector, int mode); void (*save)(struct drm_connector *connector); void (*restore)(struct drm_connector *connector); + + /* Check to see if anything is attached to the connector. + * @force is set to false whilst polling, true when checking the + * connector due to user request. @force can be used by the driver + * to avoid expensive, destructive operations during automated + * probing. + */ enum drm_connector_status (*detect)(struct drm_connector *connector, - bool nondestructive); + bool force); int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); int (*set_property)(struct drm_connector *connector, struct drm_property *property, uint64_t val); -- cgit v1.2.3 From b64c115eb22516ecd187c74ad6de3f1693f1dc7b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 14 Sep 2010 20:14:38 +1000 Subject: drm: fix race between driver loading and userspace open. Not 100% sure this is due to BKL removal, its most likely a combination of that + userspace timing changes in udev/plymouth. The drm adds the sysfs device before the driver has completed internal loading, this causes udev to make the node and plymouth to open it before we've completed loading. The proper solution is to delay the sysfs manipulation until later in loading however this causes knock on issues with sysfs connector nodes, so we can use the global mutex to serialise loading and userspace opens. Reported-by: Toni Spets (hifi on #radeon) Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_pci.c | 4 ++++ drivers/gpu/drm/drm_platform.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e20f78b542a..f5bd9e590c8 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, dev->hose = pdev->sysdata; #endif + mutex_lock(&drm_global_mutex); + if ((ret = drm_fill_in_dev(dev, ent, driver))) { printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); goto err_g2; @@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, pci_name(pdev), dev->primary->index); + mutex_unlock(&drm_global_mutex); return 0; err_g4: @@ -210,6 +213,7 @@ err_g2: pci_disable_device(pdev); err_g1: kfree(dev); + mutex_unlock(&drm_global_mutex); return ret; } EXPORT_SYMBOL(drm_get_pci_dev); diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 460e9a3afa8..92d1d0fb7b7 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev, dev->platformdev = platdev; dev->dev = &platdev->dev; + mutex_lock(&drm_global_mutex); + ret = drm_fill_in_dev(dev, NULL, driver); if (ret) { @@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev, list_add_tail(&dev->driver_item, &driver->device_list); + mutex_unlock(&drm_global_mutex); + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary->index); @@ -100,6 +104,7 @@ err_g2: drm_put_minor(&dev->control); err_g1: kfree(dev); + mutex_unlock(&drm_global_mutex); return ret; } EXPORT_SYMBOL(drm_get_platform_dev); -- cgit v1.2.3 From f90087eea44ce5fad139f086bc9d89ca37b0edc2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 7 Sep 2010 11:42:45 -0400 Subject: drm/radeon/kms: force legacy pll algo for RV620 LVDS There has been periodic evidence that LVDS, on at least some panels, prefers the dividers selected by the legacy pll algo. This patch forces the use of the legacy pll algo on RV620 LVDS panels. The old behavior (new pll algo) can be selected by setting the new_pll module parameter to 1. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=30029 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 464a81a1990..cd0290f946c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -539,14 +539,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, pll->algo = PLL_ALGO_LEGACY; pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; } - /* There is some evidence (often anecdotal) that RV515 LVDS + /* There is some evidence (often anecdotal) that RV515/RV620 LVDS * (on some boards at least) prefers the legacy algo. I'm not * sure whether this should handled generically or on a * case-by-case quirk basis. Both algos should work fine in the * majority of cases. */ if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && - (rdev->family == CHIP_RV515)) { + ((rdev->family == CHIP_RV515) || + (rdev->family == CHIP_RV620))) { /* allow the user to overrride just in case */ if (radeon_new_pll == 1) pll->algo = PLL_ALGO_NEW; -- cgit v1.2.3 From fe725d4f22f6bd1e7a5e7074bdf53a8fe0a954ee Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 14 Sep 2010 10:10:47 -0400 Subject: drm/radeon/kms: only warn on mipmap size checks in r600 cs checker (v2) The texture base address registers are in units of 256 bytes. The original CS checker treated these offsets as bytes, so the original check was wrong. I fixed the units in a patch during the 2.6.36 cycle, but this ended up breaking some existing userspace (probably due to a bug in either userspace texture allocation or the drm texture mipmap checker). So for now, until we come up with a better fix, just warn if the mipmap size it too large. This will keep existing userspace working and it should be just as safe as before when we were checking the wrong units. These are GPU MC addresses, so if they fall outside of the VRAM or GART apertures, they end up at the GPU default page, so this should be safe from a security perspective. v2: Just disable the warning. It just spams the log and there's nothing the user can do about it. Signed-off-by: Alex Deucher Cc: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index d8864949e38..250a3a91819 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i /* using get ib will give us the offset into the mipmap bo */ word0 = radeon_get_ib_value(p, idx + 3) << 8; if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { - dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", - w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); - return -EINVAL; + /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", + w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/ } return 0; } -- cgit v1.2.3