602 lines
23 KiB
Diff
602 lines
23 KiB
Diff
commit 879d56da9b89b52de2109cadf1369967522428e8
|
|
Author: Dave Airlie <airlied@redhat.com>
|
|
Date: Tue Oct 26 12:55:52 2010 +1000
|
|
|
|
drm/radeon/kms: don't poll dac load detect.
|
|
|
|
This is slightly destructive, cpu intensive and can cause lockups.
|
|
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
commit 2563a90cdda1fe490947dc032ce17bf1118afc39
|
|
Author: Dave Airlie <airlied@redhat.com>
|
|
Date: Tue Nov 9 10:26:00 2010 +1000
|
|
|
|
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 <chris@chris-wilson.co.uk>
|
|
Cc: stable@kernel.org
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
Conflicts:
|
|
|
|
drivers/gpu/drm/i915/intel_tv.c
|
|
drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
|
|
commit deb557bbbcaa7fa8281d51490c73b51f579bc84d
|
|
Author: Dave Airlie <airlied@redhat.com>
|
|
Date: Tue Nov 9 10:24:06 2010 +1000
|
|
|
|
drm: Use a nondestructive mode for output detect when polling
|
|
|
|
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 <bonbons@linux-vserver.org>
|
|
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Cc: stable@kernel.org
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
Conflicts:
|
|
|
|
drivers/gpu/drm/i915/intel_tv.c
|
|
drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
|
|
commit 8d5d3cd3612618a3c2214048788f0b2cc463ce0f
|
|
Author: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Date: Mon Sep 6 23:53:47 2010 +0100
|
|
|
|
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 <chris@chris-wilson.co.uk>
|
|
Cc: Dave Airlie <airlied@redhat.com>
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
commit ec0becade1eae9b0f40b12ea4fcc3ea36e993ba3
|
|
Author: Dave Airlie <airlied@redhat.com>
|
|
Date: Tue Nov 9 09:48:34 2010 +1000
|
|
|
|
drm/kms: Add a module parameter to disable polling
|
|
|
|
Polling for a VGA device on an old system can be quite expensive,
|
|
causing latencies on the order of 600ms. As we hold the mode mutex for
|
|
this time and also need the same mutex to move the cursor, we trigger a
|
|
user-visible stall.
|
|
|
|
The real solution would involve improving the granulatity of the
|
|
locking and so perhaps performing some of the probing not under the lock
|
|
or some other updates can be done under different locks. Also reducing the
|
|
cost of probing for a non-existent monitor would be worthwhile. However,
|
|
exposing a parameter to disable polling is a simple workaround in the
|
|
meantime.
|
|
|
|
In order to accommodate users turning polling on and off at runtime, the
|
|
polling is potentially re-enabled on every probe. This is coupled to
|
|
the user calling xrandr, which seems to be a vaild time to reset the
|
|
polling timeout since the information on the connection has just been
|
|
updated. (The presumption being that all connections are probed in a
|
|
single xrandr pass, which is currently valid.)
|
|
|
|
References:
|
|
|
|
Bug 29536 - 2.6.35 causes ~600ms latency every 10s
|
|
https://bugs.freedesktop.org/show_bug.cgi?id=29536
|
|
|
|
Bug 16265 - Why is kslowd accumulating so much CPU time?
|
|
https://bugzilla.kernel.org/show_bug.cgi?id=16265
|
|
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Reported-and-tested-by: Bruno Prémont <bonbons@linux-vserver.org>
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
Conflicts:
|
|
|
|
drivers/gpu/drm/drm_crtc_helper.c
|
|
|
|
commit 77e90256db2f7e6424717f7cc984b22d2832243f
|
|
Author: Dan Carpenter <error27@gmail.com>
|
|
Date: Thu Aug 19 11:46:29 2010 +0200
|
|
|
|
drm: move dereference below check
|
|
|
|
"fb_helper_conn" is dereferenced before the check for NULL. It's never
|
|
actually NULL here, so this is mostly to keep the static checkers happy.
|
|
|
|
Signed-off-by: Dan Carpenter <error27@gmail.com>
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
commit 86e25290d9df7a84d185dfc037851d72d270a6c0
|
|
Author: Alex Deucher <alexdeucher@gmail.com>
|
|
Date: Tue Jul 20 03:24:11 2010 -0400
|
|
|
|
drm/radeon/kms: make sure HPD is set to NONE on analog-only connectors
|
|
|
|
HPD is digital only.
|
|
|
|
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
|
|
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
|
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
|
|
index 25d70d6..d537039 100644
|
|
--- a/drivers/gpu/drm/drm_crtc_helper.c
|
|
+++ b/drivers/gpu/drm/drm_crtc_helper.c
|
|
@@ -34,6 +34,9 @@
|
|
#include "drm_crtc_helper.h"
|
|
#include "drm_fb_helper.h"
|
|
|
|
+static bool drm_kms_helper_poll = true;
|
|
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
|
|
+
|
|
static void drm_mode_validate_flag(struct drm_connector *connector,
|
|
int flags)
|
|
{
|
|
@@ -98,8 +101,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|
connector->status = connector_status_disconnected;
|
|
if (connector->funcs->force)
|
|
connector->funcs->force(connector);
|
|
- } else
|
|
- connector->status = connector->funcs->detect(connector);
|
|
+ } else {
|
|
+ connector->status = connector->funcs->detect(connector, true);
|
|
+ drm_kms_helper_poll_enable(dev);
|
|
+ }
|
|
|
|
if (connector->status == connector_status_disconnected) {
|
|
DRM_DEBUG_KMS("%s is disconnected\n",
|
|
@@ -820,6 +825,9 @@ static void output_poll_execute(struct slow_work *work)
|
|
bool repoll = false, changed = false;
|
|
int ret;
|
|
|
|
+ if (!drm_kms_helper_poll)
|
|
+ return;
|
|
+
|
|
mutex_lock(&dev->mode_config.mutex);
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
|
|
@@ -839,7 +847,7 @@ static void output_poll_execute(struct slow_work *work)
|
|
!(connector->polled & DRM_CONNECTOR_POLL_HPD))
|
|
continue;
|
|
|
|
- status = connector->funcs->detect(connector);
|
|
+ status = connector->funcs->detect(connector, false);
|
|
if (old_status != status)
|
|
changed = true;
|
|
}
|
|
@@ -874,6 +882,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
|
|
struct drm_connector *connector;
|
|
int ret;
|
|
|
|
+ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
|
|
+ return;
|
|
+
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
if (connector->polled)
|
|
poll = true;
|
|
@@ -909,9 +920,12 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
|
|
{
|
|
if (!dev->mode_config.poll_enabled)
|
|
return;
|
|
+
|
|
delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work);
|
|
/* schedule a slow work asap */
|
|
- delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
|
|
+ if (drm_kms_helper_poll)
|
|
+ delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, 0);
|
|
+
|
|
}
|
|
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
|
|
|
|
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
|
|
index 7196620..cef8d8d 100644
|
|
--- a/drivers/gpu/drm/drm_fb_helper.c
|
|
+++ b/drivers/gpu/drm/drm_fb_helper.c
|
|
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn
|
|
int i;
|
|
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
|
|
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
|
- struct drm_connector *connector = fb_helper_conn->connector;
|
|
+ struct drm_connector *connector;
|
|
|
|
if (!fb_helper_conn)
|
|
return false;
|
|
+ connector = fb_helper_conn->connector;
|
|
|
|
cmdline_mode = &fb_helper_conn->cmdline_mode;
|
|
if (!mode_option)
|
|
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
|
|
index 101d381..9500af1 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 ee0732b..3886b47 100644
|
|
--- a/drivers/gpu/drm/i915/intel_crt.c
|
|
+++ b/drivers/gpu/drm/i915/intel_crt.c
|
|
@@ -402,7 +402,8 @@ 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 force)
|
|
{
|
|
struct drm_device *dev = connector->dev;
|
|
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
|
@@ -421,6 +422,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
|
|
if (intel_crt_detect_ddc(encoder))
|
|
return connector_status_connected;
|
|
|
|
+ if (!force)
|
|
+ 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 d9de8f1..b58249d 100644
|
|
--- a/drivers/gpu/drm/i915/intel_dp.c
|
|
+++ b/drivers/gpu/drm/i915/intel_dp.c
|
|
@@ -1287,7 +1287,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)
|
|
+intel_dp_detect(struct drm_connector *connector, bool force)
|
|
{
|
|
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
|
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
|
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
|
|
index 227feca..48a1889 100644
|
|
--- a/drivers/gpu/drm/i915/intel_dvo.c
|
|
+++ b/drivers/gpu/drm/i915/intel_dvo.c
|
|
@@ -211,7 +211,8 @@ 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 force)
|
|
{
|
|
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
|
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
|
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
|
|
index 83bd764..d1decfc 100644
|
|
--- a/drivers/gpu/drm/i915/intel_hdmi.c
|
|
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
|
|
@@ -134,7 +134,7 @@ 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 force)
|
|
{
|
|
struct drm_encoder *encoder = intel_attached_encoder(connector);
|
|
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
|
|
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
|
|
index 7d42ff1..9ad3425 100644
|
|
--- a/drivers/gpu/drm/i915/intel_lvds.c
|
|
+++ b/drivers/gpu/drm/i915/intel_lvds.c
|
|
@@ -546,7 +546,8 @@ 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 force)
|
|
{
|
|
struct drm_device *dev = connector->dev;
|
|
enum drm_connector_status status = connector_status_connected;
|
|
@@ -641,7 +642,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,
|
|
+ false);
|
|
+
|
|
/* 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 76993ac..76c9b3d 100644
|
|
--- a/drivers/gpu/drm/i915/intel_sdvo.c
|
|
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
|
|
@@ -1496,7 +1496,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, false) ==
|
|
connector_status_disconnected)
|
|
return false;
|
|
|
|
@@ -1567,7 +1567,8 @@ 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 force)
|
|
{
|
|
uint16_t response;
|
|
u8 status;
|
|
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
|
|
index 6d553c2..ad40f1b 100644
|
|
--- a/drivers/gpu/drm/i915/intel_tv.c
|
|
+++ b/drivers/gpu/drm/i915/intel_tv.c
|
|
@@ -1336,7 +1336,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)
|
|
+intel_tv_detect(struct drm_connector *connector, bool force)
|
|
{
|
|
struct drm_crtc *crtc;
|
|
struct drm_display_mode mode;
|
|
@@ -1351,7 +1351,7 @@ intel_tv_detect(struct drm_connector *connector)
|
|
|
|
if (encoder->crtc && encoder->crtc->enabled) {
|
|
type = intel_tv_detect_type(encoder->crtc, intel_encoder);
|
|
- } else {
|
|
+ } else if (force) {
|
|
crtc = intel_get_load_detect_pipe(intel_encoder, connector,
|
|
&mode, &dpms_mode);
|
|
if (crtc) {
|
|
@@ -1359,8 +1359,9 @@ intel_tv_detect(struct drm_connector *connector)
|
|
intel_release_load_detect_pipe(intel_encoder, connector,
|
|
dpms_mode);
|
|
} else
|
|
- type = -1;
|
|
- }
|
|
+ return connector_status_unknown;
|
|
+ } else
|
|
+ return connector->status;
|
|
|
|
tv_priv->type = type;
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
index 149ed22..1085376 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
|
|
@@ -228,7 +228,7 @@ 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 force)
|
|
{
|
|
struct drm_device *dev = connector->dev;
|
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
|
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
|
|
index adccbc2..1680600 100644
|
|
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
|
|
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
|
|
@@ -467,7 +467,8 @@ 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 force)
|
|
{
|
|
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
|
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
|
@@ -582,7 +583,8 @@ 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 force)
|
|
{
|
|
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
|
struct drm_encoder *encoder;
|
|
@@ -621,6 +623,11 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
|
|
ret = connector_status_connected;
|
|
}
|
|
} else {
|
|
+
|
|
+ /* if we aren't forcing don't do destructive polling */
|
|
+ if (!force)
|
|
+ return connector->status;
|
|
+
|
|
if (radeon_connector->dac_load_detect && encoder) {
|
|
encoder_funcs = encoder->helper_private;
|
|
ret = encoder_funcs->detect(encoder, connector);
|
|
@@ -679,7 +686,8 @@ 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 force)
|
|
{
|
|
struct drm_encoder *encoder;
|
|
struct drm_encoder_helper_funcs *encoder_funcs;
|
|
@@ -736,7 +744,8 @@ 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 force)
|
|
{
|
|
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
|
struct drm_encoder *encoder = NULL;
|
|
@@ -806,6 +815,11 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
|
|
if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
|
|
goto out;
|
|
|
|
+ if (!force) {
|
|
+ ret = connector->status;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
/* find analog encoder */
|
|
if (radeon_connector->dac_load_detect) {
|
|
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
|
@@ -962,7 +976,8 @@ 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 force)
|
|
{
|
|
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
|
enum drm_connector_status ret = connector_status_disconnected;
|
|
@@ -1082,6 +1097,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.load_detect_property,
|
|
1);
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
|
connector->interlace_allowed = true;
|
|
connector->doublescan_allowed = true;
|
|
@@ -1096,6 +1113,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.load_detect_property,
|
|
1);
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
connector->interlace_allowed = true;
|
|
connector->doublescan_allowed = true;
|
|
break;
|
|
@@ -1186,6 +1205,8 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.tv_std_property,
|
|
radeon_atombios_get_tv_info(rdev));
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
}
|
|
connector->interlace_allowed = false;
|
|
connector->doublescan_allowed = false;
|
|
@@ -1209,7 +1230,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|
break;
|
|
}
|
|
|
|
- if (hpd->hpd == RADEON_HPD_NONE) {
|
|
+ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
|
|
if (i2c_bus->valid)
|
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
|
} else
|
|
@@ -1276,6 +1297,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.load_detect_property,
|
|
1);
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
|
connector->interlace_allowed = true;
|
|
connector->doublescan_allowed = true;
|
|
@@ -1290,6 +1313,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.load_detect_property,
|
|
1);
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
connector->interlace_allowed = true;
|
|
connector->doublescan_allowed = true;
|
|
break;
|
|
@@ -1328,6 +1353,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|
drm_connector_attach_property(&radeon_connector->base,
|
|
rdev->mode_info.tv_std_property,
|
|
radeon_combios_get_tv_info(rdev));
|
|
+ /* no HPD on analog connectors */
|
|
+ radeon_connector->hpd.hpd = RADEON_HPD_NONE;
|
|
}
|
|
connector->interlace_allowed = false;
|
|
connector->doublescan_allowed = false;
|
|
@@ -1345,7 +1372,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|
break;
|
|
}
|
|
|
|
- if (hpd->hpd == RADEON_HPD_NONE) {
|
|
+ if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
|
|
if (i2c_bus->valid)
|
|
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
|
} else
|
|
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
|
|
index cfaf690..5b638cb 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 force)
|
|
{
|
|
if (vmw_connector_to_ldu(connector)->pref_active)
|
|
return connector_status_connected;
|
|
@@ -516,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);
|
|
@@ -610,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 93a1a31..afbb578 100644
|
|
--- a/include/drm/drm_crtc.h
|
|
+++ b/include/drm/drm_crtc.h
|
|
@@ -420,7 +420,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);
|
|
- enum drm_connector_status (*detect)(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 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);
|