05493c4
commit 879d56da9b89b52de2109cadf1369967522428e8
05493c4
Author: Dave Airlie <airlied@redhat.com>
05493c4
Date:   Tue Oct 26 12:55:52 2010 +1000
05493c4
05493c4
    drm/radeon/kms: don't poll dac load detect.
05493c4
    
05493c4
    This is slightly destructive, cpu intensive and can cause lockups.
05493c4
    
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
05493c4
commit 2563a90cdda1fe490947dc032ce17bf1118afc39
05493c4
Author: Dave Airlie <airlied@redhat.com>
05493c4
Date:   Tue Nov 9 10:26:00 2010 +1000
05493c4
05493c4
    drm: Use a nondestructive mode for output detect when polling (v2)
05493c4
    
05493c4
    v2: Julien Cristau pointed out that @nondestructive results in
05493c4
    double-negatives and confusion when trying to interpret the parameter,
05493c4
    so use @force instead. Much easier to type as well. ;-)
05493c4
    
05493c4
    And fix the miscompilation of vmgfx reported by Sedat Dilek.
05493c4
    
05493c4
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
05493c4
    Cc: stable@kernel.org
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
    
05493c4
    Conflicts:
05493c4
    
05493c4
    	drivers/gpu/drm/i915/intel_tv.c
05493c4
    	drivers/gpu/drm/nouveau/nouveau_connector.c
05493c4
05493c4
commit deb557bbbcaa7fa8281d51490c73b51f579bc84d
05493c4
Author: Dave Airlie <airlied@redhat.com>
05493c4
Date:   Tue Nov 9 10:24:06 2010 +1000
05493c4
05493c4
    drm: Use a nondestructive mode for output detect when polling
05493c4
    
05493c4
    Destructive load-detection is very expensive and due to failings
05493c4
    elsewhere can trigger system wide stalls of up to 600ms. A simple
05493c4
    first step to correcting this is not to invoke such an expensive
05493c4
    and destructive load-detection operation automatically.
05493c4
    
05493c4
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29536
05493c4
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16265
05493c4
    Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
05493c4
    Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
05493c4
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
05493c4
    Cc: stable@kernel.org
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
    
05493c4
    Conflicts:
05493c4
    
05493c4
    	drivers/gpu/drm/i915/intel_tv.c
05493c4
    	drivers/gpu/drm/nouveau/nouveau_connector.c
05493c4
05493c4
commit 8d5d3cd3612618a3c2214048788f0b2cc463ce0f
05493c4
Author: Chris Wilson <chris@chris-wilson.co.uk>
05493c4
Date:   Mon Sep 6 23:53:47 2010 +0100
05493c4
05493c4
    drm: Fix regression in disable polling e58f637
05493c4
    
05493c4
    I broke out my trusty i845 and found a new boot failure, which upon
05493c4
    inspection turned out to be a recursion within:
05493c4
    
05493c4
    drm_helper_probe_single_connector_modes() -> drm_helper_hpd_irq_event()
05493c4
    -> intel_crt_detect() -> drm_helper_probe_single_connector_modes()
05493c4
    
05493c4
    Calling drm_kms_helper_poll_enable() instead performs the desired
05493c4
    re-initialisation of the polling should the user have toggled the
05493c4
    parameter, without the recursive side-effect.
05493c4
    
05493c4
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
05493c4
    Cc: Dave Airlie <airlied@redhat.com>
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
05493c4
commit ec0becade1eae9b0f40b12ea4fcc3ea36e993ba3
05493c4
Author: Dave Airlie <airlied@redhat.com>
05493c4
Date:   Tue Nov 9 09:48:34 2010 +1000
05493c4
05493c4
    drm/kms: Add a module parameter to disable polling
05493c4
    
05493c4
    Polling for a VGA device on an old system can be quite expensive,
05493c4
    causing latencies on the order of 600ms. As we hold the mode mutex for
05493c4
    this time and also need the same mutex to move the cursor, we trigger a
05493c4
    user-visible stall.
05493c4
    
05493c4
    The real solution would involve improving the granulatity of the
05493c4
    locking and so perhaps performing some of the probing not under the lock
05493c4
    or some other updates can be done under different locks. Also reducing the
05493c4
    cost of probing for a non-existent monitor would be worthwhile. However,
05493c4
    exposing a parameter to disable polling is a simple workaround in the
05493c4
    meantime.
05493c4
    
05493c4
    In order to accommodate users turning polling on and off at runtime, the
05493c4
    polling is potentially re-enabled on every probe. This is coupled to
05493c4
    the user calling xrandr, which seems to be a vaild time to reset the
05493c4
    polling timeout since the information on the connection has just been
05493c4
    updated. (The presumption being that all connections are probed in a
05493c4
    single xrandr pass, which is currently valid.)
05493c4
    
05493c4
    References:
05493c4
    
05493c4
      Bug 29536 - 2.6.35 causes ~600ms latency every 10s
05493c4
      https://bugs.freedesktop.org/show_bug.cgi?id=29536
05493c4
    
05493c4
      Bug 16265 - Why is kslowd accumulating so much CPU time?
05493c4
      https://bugzilla.kernel.org/show_bug.cgi?id=16265
05493c4
    
05493c4
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
05493c4
    Reported-and-tested-by: Bruno Prémont <bonbons@linux-vserver.org>
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
    
05493c4
    Conflicts:
05493c4
    
05493c4
    	drivers/gpu/drm/drm_crtc_helper.c
05493c4
05493c4
commit 77e90256db2f7e6424717f7cc984b22d2832243f
05493c4
Author: Dan Carpenter <error27@gmail.com>
05493c4
Date:   Thu Aug 19 11:46:29 2010 +0200
05493c4
05493c4
    drm: move dereference below check
05493c4
    
05493c4
    "fb_helper_conn" is dereferenced before the check for NULL.  It's never
05493c4
    actually NULL here, so this is mostly to keep the static checkers happy.
05493c4
    
05493c4
    Signed-off-by: Dan Carpenter <error27@gmail.com>
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
05493c4
commit 86e25290d9df7a84d185dfc037851d72d270a6c0
05493c4
Author: Alex Deucher <alexdeucher@gmail.com>
05493c4
Date:   Tue Jul 20 03:24:11 2010 -0400
05493c4
05493c4
    drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors
05493c4
    
05493c4
    HPD is digital only.
05493c4
    
05493c4
    Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
05493c4
commit 93d2725f536c17a85c35051beb4c41b7c1707db0
05493c4
Author: Alex Deucher <alexdeucher@gmail.com>
05493c4
Date:   Mon Oct 25 19:44:00 2010 -0400
05493c4
05493c4
    drm/radeon/kms: MC vram map needs to be >= pci aperture size
05493c4
    
05493c4
    The vram map in the radeon memory controller needs to be
05493c4
    >= the pci aperture size.  Fixes:
05493c4
    https://bugs.freedesktop.org/show_bug.cgi?id=28402
05493c4
    
05493c4
    The problematic cards in the above bug have 64 MB of vram,
05493c4
    but the pci aperture is 128 MB and the MC vram map was only
05493c4
    64 MB.  This can lead to hangs.
05493c4
    
05493c4
    Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
05493c4
    Cc: stable@kernel.org
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
05493c4
commit 3fd6d68cfa32d8a5c99ba24e3d2c669bffef45ec
05493c4
Author: Alex Deucher <alexdeucher@gmail.com>
05493c4
Date:   Wed Oct 27 01:02:35 2010 -0400
05493c4
05493c4
    drm/radeon/kms: fix handling of tex lookup disable in cs checker on r2xx
05493c4
    
05493c4
    There are cases when multiple texture units have to be enabled,
05493c4
    but not actually used to sample.  This patch checks to see if
05493c4
    the lookup_disable bit is set and if so, skips the texture check.
05493c4
    
05493c4
    Fixes:
05493c4
    https://bugs.freedesktop.org/show_bug.cgi?id=25544
05493c4
    
05493c4
    Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
05493c4
    Cc: stable@kernel.org
05493c4
    Signed-off-by: Dave Airlie <airlied@redhat.com>
05493c4
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
05493c4
index 25d70d6..d537039 100644
05493c4
--- a/drivers/gpu/drm/drm_crtc_helper.c
05493c4
+++ b/drivers/gpu/drm/drm_crtc_helper.c
05493c4
@@ -34,6 +34,9 @@
05493c4
 #include "drm_crtc_helper.h"
05493c4
 #include "drm_fb_helper.h"
05493c4
 
05493c4
+static bool drm_kms_helper_poll = true;
05493c4
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
05493c4
+
05493c4
 static void drm_mode_validate_flag(struct drm_connector *connector,
05493c4
 				   int flags)
05493c4
 {
05493c4
@@ -98,8 +101,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
05493c4
 			connector->status = connector_status_disconnected;
05493c4
 		if (connector->funcs->force)
05493c4
 			connector->funcs->force(connector);
05493c4
-	} else
05493c4
-		connector->status = connector->funcs->detect(connector);
05493c4
+	} else {
05493c4
+		connector->status = connector->funcs->detect(connector, true);
05493c4
+		drm_kms_helper_poll_enable(dev);
05493c4
+	}
05493c4
 
05493c4
 	if (connector->status == connector_status_disconnected) {
05493c4
 		DRM_DEBUG_KMS("%s is disconnected\n",
05493c4
@@ -820,6 +825,9 @@ static void output_poll_execute(struct slow_work *work)
05493c4
 	bool repoll = false, changed = false;
05493c4
 	int ret;
05493c4
 
05493c4
+	if (!drm_kms_helper_poll)
05493c4
+		return;
05493c4
+
05493c4
 	mutex_lock(&dev->mode_config.mutex);
05493c4
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
05493c4
 
05493c4
@@ -839,7 +847,7 @@ static void output_poll_execute(struct slow_work *work)
05493c4
 		    !(connector->polled & DRM_CONNECTOR_POLL_HPD))
05493c4
 			continue;
05493c4
 
05493c4
-		status = connector->funcs->detect(connector);
05493c4
+		status = connector->funcs->detect(connector, false);
05493c4
 		if (old_status != status)
05493c4
 			changed = true;
05493c4
 	}
05493c4
@@ -874,6 +882,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
05493c4
 	struct drm_connector *connector;
05493c4
 	int ret;
05493c4
 
05493c4
+	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
05493c4
+		return;
05493c4
+
05493c4
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
05493c4
 		if (connector->polled)
05493c4
 			poll = true;
05493c4
@@ -909,9 +920,12 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
05493c4
 {
05493c4
 	if (!dev->mode_config.poll_enabled)
05493c4
 		return;
05493c4
+
05493c4
 	delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
05493c4
 	/* schedule a slow work asap */
05493c4
-	delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
05493c4
+	if (drm_kms_helper_poll)
05493c4
+		delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
05493c4
+
05493c4
 }
05493c4
 EXPORT_SYMBOL(drm_helper_hpd_irq_event);
05493c4
 
05493c4
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
05493c4
index 7196620..cef8d8d 100644
05493c4
--- a/drivers/gpu/drm/drm_fb_helper.c
05493c4
+++ b/drivers/gpu/drm/drm_fb_helper.c
05493c4
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn
05493c4
 	int i;
05493c4
 	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
05493c4
 	struct drm_fb_helper_cmdline_mode *cmdline_mode;
05493c4
-	struct drm_connector *connector = fb_helper_conn->connector;
05493c4
+	struct drm_connector *connector;
05493c4
 
05493c4
 	if (!fb_helper_conn)
05493c4
 		return false;
05493c4
+	connector = fb_helper_conn->connector;
05493c4
 
05493c4
 	cmdline_mode = &fb_helper_conn->cmdline_mode;
05493c4
 	if (!mode_option)
05493c4
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
05493c4
index 101d381..9500af1 100644
05493c4
--- a/drivers/gpu/drm/drm_sysfs.c
05493c4
+++ b/drivers/gpu/drm/drm_sysfs.c
05493c4
@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device,
05493c4
 	struct drm_connector *connector = to_drm_connector(device);
05493c4
 	enum drm_connector_status status;
05493c4
 
05493c4
-	status = connector->funcs->detect(connector);
05493c4
+	status = connector->funcs->detect(connector, true);
05493c4
 	return snprintf(buf, PAGE_SIZE, "%s\n",
05493c4
 			drm_get_connector_status_name(status));
05493c4
 }
05493c4
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
05493c4
index ee0732b..3886b47 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_crt.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_crt.c
05493c4
@@ -402,7 +402,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
05493c4
 	return status;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+intel_crt_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_device *dev = connector->dev;
05493c4
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
05493c4
@@ -421,6 +422,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
05493c4
 	if (intel_crt_detect_ddc(encoder))
05493c4
 		return connector_status_connected;
05493c4
 
05493c4
+	if (!force)
05493c4
+		return connector->status;
05493c4
+
05493c4
 	/* for pre-945g platforms use load detect */
05493c4
 	if (encoder->crtc && encoder->crtc->enabled) {
05493c4
 		status = intel_crt_load_detect(encoder->crtc, intel_encoder);
05493c4
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
05493c4
index d9de8f1..b58249d 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_dp.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_dp.c
05493c4
@@ -1287,7 +1287,7 @@ ironlake_dp_detect(struct drm_connector *connector)
05493c4
  * \return false if DP port is disconnected.
05493c4
  */
05493c4
 static enum drm_connector_status
05493c4
-intel_dp_detect(struct drm_connector *connector)
05493c4
+intel_dp_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
05493c4
 	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
05493c4
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
05493c4
index 227feca..48a1889 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_dvo.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_dvo.c
05493c4
@@ -211,7 +211,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
05493c4
  *
05493c4
  * Unimplemented.
05493c4
  */
05493c4
-static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+intel_dvo_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
05493c4
 	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
05493c4
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
05493c4
index 83bd764..d1decfc 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_hdmi.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
05493c4
@@ -134,7 +134,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
05493c4
 }
05493c4
 
05493c4
 static enum drm_connector_status
05493c4
-intel_hdmi_detect(struct drm_connector *connector)
05493c4
+intel_hdmi_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_encoder *encoder = intel_attached_encoder(connector);
05493c4
 	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
05493c4
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
05493c4
index 7d42ff1..9ad3425 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_lvds.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_lvds.c
05493c4
@@ -546,7 +546,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
05493c4
  * connected and closed means disconnected.  We also send hotplug events as
05493c4
  * needed, using lid status notification from the input layer.
05493c4
  */
05493c4
-static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+intel_lvds_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_device *dev = connector->dev;
05493c4
 	enum drm_connector_status status = connector_status_connected;
05493c4
@@ -641,7 +642,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
05493c4
 	 * the LID nofication event.
05493c4
 	 */
05493c4
 	if (connector)
05493c4
-		connector->status = connector->funcs->detect(connector);
05493c4
+		connector->status = connector->funcs->detect(connector,
05493c4
+							     false);
05493c4
+
05493c4
 	/* Don't force modeset on machines where it causes a GPU lockup */
05493c4
 	if (dmi_check_system(intel_no_modeset_on_lid))
05493c4
 		return NOTIFY_OK;
05493c4
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
05493c4
index 76993ac..76c9b3d 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_sdvo.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
05493c4
@@ -1496,7 +1496,7 @@ intel_analog_is_connected(struct drm_device *dev)
05493c4
 	if (!analog_connector)
05493c4
 		return false;
05493c4
 
05493c4
-	if (analog_connector->funcs->detect(analog_connector) ==
05493c4
+	if (analog_connector->funcs->detect(analog_connector, false) ==
05493c4
 			connector_status_disconnected)
05493c4
 		return false;
05493c4
 
05493c4
@@ -1567,7 +1567,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
05493c4
 	return status;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+intel_sdvo_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	uint16_t response;
05493c4
 	u8 status;
05493c4
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
05493c4
index 6d553c2..ad40f1b 100644
05493c4
--- a/drivers/gpu/drm/i915/intel_tv.c
05493c4
+++ b/drivers/gpu/drm/i915/intel_tv.c
05493c4
@@ -1336,7 +1336,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
05493c4
  * we have a pipe programmed in order to probe the TV.
05493c4
  */
05493c4
 static enum drm_connector_status
05493c4
-intel_tv_detect(struct drm_connector *connector)
05493c4
+intel_tv_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_crtc *crtc;
05493c4
 	struct drm_display_mode mode;
05493c4
@@ -1351,7 +1351,7 @@ intel_tv_detect(struct drm_connector *connector)
05493c4
 
05493c4
 	if (encoder->crtc && encoder->crtc->enabled) {
05493c4
 		type = intel_tv_detect_type(encoder->crtc, intel_encoder);
05493c4
-	} else {
05493c4
+	} else if (force) {
05493c4
 		crtc = intel_get_load_detect_pipe(intel_encoder, connector,
05493c4
 						  &mode, &dpms_mode);
05493c4
 		if (crtc) {
05493c4
@@ -1359,8 +1359,9 @@ intel_tv_detect(struct drm_connector *connector)
05493c4
 			intel_release_load_detect_pipe(intel_encoder, connector,
05493c4
 						       dpms_mode);
05493c4
 		} else
05493c4
-			type = -1;
05493c4
-	}
05493c4
+			return connector_status_unknown;
05493c4
+	} else
05493c4
+		return connector->status;
05493c4
 
05493c4
 	tv_priv->type = type;
05493c4
 
05493c4
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
05493c4
index 149ed22..1085376 100644
05493c4
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
05493c4
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
05493c4
@@ -228,7 +228,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
05493c4
 }
05493c4
 
05493c4
 static enum drm_connector_status
05493c4
-nouveau_connector_detect(struct drm_connector *connector)
05493c4
+nouveau_connector_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_device *dev = connector->dev;
05493c4
 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
05493c4
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
05493c4
index a89a15a..a3378ba 100644
05493c4
--- a/drivers/gpu/drm/radeon/r100.c
05493c4
+++ b/drivers/gpu/drm/radeon/r100.c
05493c4
@@ -2321,6 +2321,9 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
05493c4
 		/* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - 
05493c4
 		 * Novell bug 204882 + along with lots of ubuntu ones
05493c4
 		 */
05493c4
+		if (rdev->mc.aper_size > config_aper_size)
05493c4
+			config_aper_size = rdev->mc.aper_size;
05493c4
+
05493c4
 		if (config_aper_size > rdev->mc.real_vram_size)
05493c4
 			rdev->mc.mc_vram_size = config_aper_size;
05493c4
 		else
05493c4
@@ -3229,6 +3232,8 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
05493c4
 	for (u = 0; u < track->num_texture; u++) {
05493c4
 		if (!track->textures[u].enabled)
05493c4
 			continue;
05493c4
+		if (track->textures[u].lookup_disable)
05493c4
+			continue;
05493c4
 		robj = track->textures[u].robj;
05493c4
 		if (robj == NULL) {
05493c4
 			DRM_ERROR("No texture bound to unit %u\n", u);
05493c4
@@ -3462,6 +3467,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
05493c4
 		track->textures[i].robj = NULL;
05493c4
 		/* CS IB emission code makes sure texture unit are disabled */
05493c4
 		track->textures[i].enabled = false;
05493c4
+		track->textures[i].lookup_disable = false;
05493c4
 		track->textures[i].roundup_w = true;
05493c4
 		track->textures[i].roundup_h = true;
05493c4
 		if (track->separate_cube)
05493c4
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
05493c4
index f47cdca..af65600 100644
05493c4
--- a/drivers/gpu/drm/radeon/r100_track.h
05493c4
+++ b/drivers/gpu/drm/radeon/r100_track.h
05493c4
@@ -46,6 +46,7 @@ struct r100_cs_track_texture {
05493c4
 	unsigned		height_11;
05493c4
 	bool			use_pitch;
05493c4
 	bool			enabled;
05493c4
+	bool                    lookup_disable;
05493c4
 	bool			roundup_w;
05493c4
 	bool			roundup_h;
05493c4
 	unsigned                compress_format;
05493c4
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
05493c4
index 0266d72..d2408c3 100644
05493c4
--- a/drivers/gpu/drm/radeon/r200.c
05493c4
+++ b/drivers/gpu/drm/radeon/r200.c
05493c4
@@ -447,6 +447,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
05493c4
 			track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
05493c4
 			track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
05493c4
 		}
05493c4
+		if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
05493c4
+			track->textures[i].lookup_disable = true;
05493c4
 		switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
05493c4
 		case R200_TXFORMAT_I8:
05493c4
 		case R200_TXFORMAT_RGB332:
05493c4
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
05493c4
index adccbc2..1680600 100644
05493c4
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
05493c4
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
05493c4
@@ -467,7 +467,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector,
05493c4
 	return MODE_OK;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+radeon_lvds_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
05493c4
 	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
05493c4
@@ -582,7 +583,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector,
05493c4
 	return MODE_OK;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+radeon_vga_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
05493c4
 	struct drm_encoder *encoder;
05493c4
@@ -621,6 +623,11 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
05493c4
 				ret = connector_status_connected;
05493c4
 		}
05493c4
 	} else {
05493c4
+
05493c4
+		/* if we aren't forcing don't do destructive polling */
05493c4
+		if (!force)
05493c4
+			return connector->status;
05493c4
+
05493c4
 		if (radeon_connector->dac_load_detect && encoder) {
05493c4
 			encoder_funcs = encoder->helper_private;
05493c4
 			ret = encoder_funcs->detect(encoder, connector);
05493c4
@@ -679,7 +686,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector,
05493c4
 	return MODE_OK;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+radeon_tv_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct drm_encoder *encoder;
05493c4
 	struct drm_encoder_helper_funcs *encoder_funcs;
05493c4
@@ -736,7 +744,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector)
05493c4
  * we have to check if this analog encoder is shared with anyone else (TV)
05493c4
  * if its shared we have to set the other connector to disconnected.
05493c4
  */
05493c4
-static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+radeon_dvi_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
05493c4
 	struct drm_encoder *encoder = NULL;
05493c4
@@ -806,6 +815,11 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
05493c4
 	if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
05493c4
 		goto out;
05493c4
 
05493c4
+	if (!force) {
05493c4
+		ret = connector->status;
05493c4
+		goto out;
05493c4
+	}
05493c4
+
05493c4
 	/* find analog encoder */
05493c4
 	if (radeon_connector->dac_load_detect) {
05493c4
 		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
05493c4
@@ -962,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
05493c4
 	return ret;
05493c4
 }
05493c4
 
05493c4
-static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
05493c4
+static enum drm_connector_status
05493c4
+radeon_dp_detect(struct drm_connector *connector, bool force)
05493c4
 {
05493c4
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
05493c4
 	enum drm_connector_status ret = connector_status_disconnected;
05493c4
@@ -1082,6 +1097,8 @@ radeon_add_atom_connector(struct drm_device *dev,
05493c4
 		drm_connector_attach_property(&radeon_connector->base,
05493c4
 					      rdev->mode_info.load_detect_property,
05493c4
 					      1);
05493c4
+		/* no HPD on analog connectors */
05493c4
+		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_DVIA:
05493c4
@@ -1096,6 +1113,8 @@ radeon_add_atom_connector(struct drm_device *dev,
05493c4
 		drm_connector_attach_property(&radeon_connector->base,
05493c4
 					      rdev->mode_info.load_detect_property,
05493c4
 					      1);
05493c4
+		/* no HPD on analog connectors */
05493c4
+		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_DVII:
05493c4
 	case DRM_MODE_CONNECTOR_DVID:
05493c4
@@ -1186,6 +1205,8 @@ radeon_add_atom_connector(struct drm_device *dev,
05493c4
 			drm_connector_attach_property(&radeon_connector->base,
05493c4
 						      rdev->mode_info.tv_std_property,
05493c4
 						      radeon_atombios_get_tv_info(rdev));
05493c4
+			/* no HPD on analog connectors */
05493c4
+			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		}
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_LVDS:
05493c4
@@ -1209,7 +1230,7 @@ radeon_add_atom_connector(struct drm_device *dev,
05493c4
 		break;
05493c4
 	}
05493c4
 
05493c4
-	if (hpd->hpd == RADEON_HPD_NONE) {
05493c4
+	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
05493c4
 		if (i2c_bus->valid)
05493c4
 			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
05493c4
 	} else
05493c4
@@ -1276,6 +1297,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
05493c4
 		drm_connector_attach_property(&radeon_connector->base,
05493c4
 					      rdev->mode_info.load_detect_property,
05493c4
 					      1);
05493c4
+		/* no HPD on analog connectors */
05493c4
+		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_DVIA:
05493c4
@@ -1290,6 +1313,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
05493c4
 		drm_connector_attach_property(&radeon_connector->base,
05493c4
 					      rdev->mode_info.load_detect_property,
05493c4
 					      1);
05493c4
+		/* no HPD on analog connectors */
05493c4
+		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_DVII:
05493c4
 	case DRM_MODE_CONNECTOR_DVID:
05493c4
@@ -1328,6 +1353,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
05493c4
 			drm_connector_attach_property(&radeon_connector->base,
05493c4
 						      rdev->mode_info.tv_std_property,
05493c4
 						      radeon_combios_get_tv_info(rdev));
05493c4
+			/* no HPD on analog connectors */
05493c4
+			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
05493c4
 		}
05493c4
 		break;
05493c4
 	case DRM_MODE_CONNECTOR_LVDS:
05493c4
@@ -1345,7 +1372,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
05493c4
 		break;
05493c4
 	}
05493c4
 
05493c4
-	if (hpd->hpd == RADEON_HPD_NONE) {
05493c4
+	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
05493c4
 		if (i2c_bus->valid)
05493c4
 			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
05493c4
 	} else
05493c4
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
05493c4
index c332f46..6492881 100644
05493c4
--- a/drivers/gpu/drm/radeon/radeon_reg.h
05493c4
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
05493c4
@@ -2836,6 +2836,7 @@
05493c4
 #       define R200_TXFORMAT_ST_ROUTE_STQ5	(5 << 24)
05493c4
 #       define R200_TXFORMAT_ST_ROUTE_MASK	(7 << 24)
05493c4
 #       define R200_TXFORMAT_ST_ROUTE_SHIFT	24
05493c4
+#       define R200_TXFORMAT_LOOKUP_DISABLE	(1 << 27)
05493c4
 #       define R200_TXFORMAT_ALPHA_MASK_ENABLE	(1 << 28)
05493c4
 #       define R200_TXFORMAT_CHROMA_KEY_ENABLE	(1 << 29)
05493c4
 #       define R200_TXFORMAT_CUBIC_MAP_ENABLE		(1 << 30)
05493c4
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
05493c4
index cfaf690..5b638cb 100644
05493c4
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
05493c4
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
05493c4
@@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
05493c4
 }
05493c4
 
05493c4
 static enum drm_connector_status
05493c4
-	vmw_ldu_connector_detect(struct drm_connector *connector)
05493c4
+	vmw_ldu_connector_detect(struct drm_connector *connector,
05493c4
+				 bool force)
05493c4
 {
05493c4
 	if (vmw_connector_to_ldu(connector)->pref_active)
05493c4
 		return connector_status_connected;
05493c4
@@ -516,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
05493c4
 
05493c4
 	drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
05493c4
 			   DRM_MODE_CONNECTOR_LVDS);
05493c4
-	connector->status = vmw_ldu_connector_detect(connector);
05493c4
+	connector->status = vmw_ldu_connector_detect(connector, true);
05493c4
 
05493c4
 	drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
05493c4
 			 DRM_MODE_ENCODER_LVDS);
05493c4
@@ -610,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
05493c4
 			ldu->pref_height = 600;
05493c4
 			ldu->pref_active = false;
05493c4
 		}
05493c4
-		con->status = vmw_ldu_connector_detect(con);
05493c4
+		con->status = vmw_ldu_connector_detect(con, true);
05493c4
 	}
05493c4
 
05493c4
 	mutex_unlock(&dev->mode_config.mutex);
05493c4
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
05493c4
index 93a1a31..afbb578 100644
05493c4
--- a/include/drm/drm_crtc.h
05493c4
+++ b/include/drm/drm_crtc.h
05493c4
@@ -420,7 +420,15 @@ struct drm_connector_funcs {
05493c4
 	void (*dpms)(struct drm_connector *connector, int mode);
05493c4
 	void (*save)(struct drm_connector *connector);
05493c4
 	void (*restore)(struct drm_connector *connector);
05493c4
-	enum drm_connector_status (*detect)(struct drm_connector *connector);
05493c4
+
05493c4
+	/* Check to see if anything is attached to the connector.
05493c4
+	 * @force is set to false whilst polling, true when checking the
05493c4
+	 * connector due to user request. @force can be used by the driver
05493c4
+	 * to avoid expensive, destructive operations during automated
05493c4
+	 * probing.
05493c4
+	 */
05493c4
+	enum drm_connector_status (*detect)(struct drm_connector *connector,
05493c4
+					    bool force);
05493c4
 	int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
05493c4
 	int (*set_property)(struct drm_connector *connector, struct drm_property *property,
05493c4
 			     uint64_t val);