From: Matthew Garrett <mjg59@srcf.ucam.org>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Andreas Heider <andreas@meetr.de>,
Arun Raghavan <arun.raghavan@collabora.co.uk>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] apple-gmux: Restore switch registers on suspend/resume
Date: Sun, 29 Jul 2012 20:39:53 +0100 [thread overview]
Message-ID: <20120729193953.GA25132@srcf.ucam.org> (raw)
In-Reply-To: <1343524730.1962.5.camel@shinybook.infradead.org>
Working: Modeline 10:"1920x1200" 60
154000 1920 1968 2000 2080 1200 1203 1209 1235 0x48 0xa
Broken: Modeline 20:"1280x800" 60 72500 1280 1328 1360 1423 800 803 809
846 0x8 0xa
And it looks like intel_lvds->edid is only set during intel_lvds_init().
That seems less than ideal. How about something like this entirely
untested patch?
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 36822b9..adef587 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1250,6 +1250,7 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
/* i915 resume handler doesn't set to D0 */
pci_set_power_state(dev->pdev, PCI_D0);
+ intel_lvds_get_edid(dev);
i915_resume(dev);
dev->switch_power_state = DRM_SWITCH_POWER_ON;
} else {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3e09188..930542a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -353,6 +353,7 @@ extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev,
struct drm_i915_gem_object *obj);
+extern bool intel_lvds_get_edid(struct drm_device *dev);
extern bool intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
void
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 08eb04c..80832e5 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -894,6 +894,59 @@ static bool intel_lvds_supported(struct drm_device *dev)
return IS_MOBILE(dev) && !IS_I830(dev);
}
+bool intel_lvds_get_edid(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_connector *connector = dev_priv->int_lvds_connector;
+ struct intel_lvds *intel_lvds;
+ struct drm_display_mode *scan; /* *modes, *bios_mode; */
+ u8 pin;
+
+ if (!connector)
+ return false;
+
+ intel_lvds = intel_attached_lvds(connector);
+
+ pin = GMBUS_PORT_PANEL;
+
+ intel_lvds->edid = drm_get_edid(connector,
+ intel_gmbus_get_adapter(dev_priv,
+ pin));
+ if (intel_lvds->edid) {
+ if (drm_add_edid_modes(connector,
+ intel_lvds->edid)) {
+ drm_mode_connector_update_edid_property(connector,
+ intel_lvds->edid);
+ } else {
+ kfree(intel_lvds->edid);
+ intel_lvds->edid = NULL;
+ }
+ }
+
+ if (!intel_lvds->edid) {
+ /* Didn't get an EDID, so
+ * Set wide sync ranges so we get all modes
+ * handed to valid_mode for checking
+ */
+ connector->display_info.min_vfreq = 0;
+ connector->display_info.max_vfreq = 200;
+ connector->display_info.min_hfreq = 0;
+ connector->display_info.max_hfreq = 200;
+ }
+
+ list_for_each_entry(scan, &connector->probed_modes, head) {
+ if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+ intel_lvds->fixed_mode =
+ drm_mode_duplicate(dev, scan);
+ intel_find_lvds_downclock(dev,
+ intel_lvds->fixed_mode,
+ connector);
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* intel_lvds_init - setup LVDS connectors on this device
* @dev: drm device
@@ -909,7 +962,6 @@ bool intel_lvds_init(struct drm_device *dev)
struct intel_connector *intel_connector;
struct drm_connector *connector;
struct drm_encoder *encoder;
- struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc;
u32 lvds;
int pipe;
@@ -976,6 +1028,8 @@ bool intel_lvds_init(struct drm_device *dev)
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
+ dev_priv->int_lvds_connector = connector;
+
/* create the scaling mode property */
drm_mode_create_scaling_mode_property(dev);
/*
@@ -1000,40 +1054,8 @@ bool intel_lvds_init(struct drm_device *dev)
* Attempt to get the fixed panel mode from DDC. Assume that the
* preferred mode is the right one.
*/
- intel_lvds->edid = drm_get_edid(connector,
- intel_gmbus_get_adapter(dev_priv,
- pin));
- if (intel_lvds->edid) {
- if (drm_add_edid_modes(connector,
- intel_lvds->edid)) {
- drm_mode_connector_update_edid_property(connector,
- intel_lvds->edid);
- } else {
- kfree(intel_lvds->edid);
- intel_lvds->edid = NULL;
- }
- }
- if (!intel_lvds->edid) {
- /* Didn't get an EDID, so
- * Set wide sync ranges so we get all modes
- * handed to valid_mode for checking
- */
- connector->display_info.min_vfreq = 0;
- connector->display_info.max_vfreq = 200;
- connector->display_info.min_hfreq = 0;
- connector->display_info.max_hfreq = 200;
- }
-
- list_for_each_entry(scan, &connector->probed_modes, head) {
- if (scan->type & DRM_MODE_TYPE_PREFERRED) {
- intel_lvds->fixed_mode =
- drm_mode_duplicate(dev, scan);
- intel_find_lvds_downclock(dev,
- intel_lvds->fixed_mode,
- connector);
- goto out;
- }
- }
+ if (intel_lvds_get_edid(dev))
+ goto out;
/* Failed to get EDID, what about VBT? */
if (dev_priv->lfp_lvds_vbt_mode) {
@@ -1112,7 +1134,6 @@ out:
dev_priv->lid_notifier.notifier_call = NULL;
}
/* keep the LVDS connector */
- dev_priv->int_lvds_connector = connector;
drm_sysfs_connector_add(connector);
intel_panel_setup_backlight(dev);
@@ -1121,6 +1142,7 @@ out:
failed:
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
+ dev_priv->int_lvds_connector = NULL;
drm_connector_cleanup(connector);
drm_encoder_cleanup(encoder);
kfree(intel_lvds);
--
Matthew Garrett | mjg59@srcf.ucam.org
next prev parent reply other threads:[~2012-07-29 19:40 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-10 3:39 [PATCH] apple-gmux: Restore switch registers on suspend/resume Arun Raghavan
2012-07-10 13:35 ` Seth Forshee
2012-07-10 16:05 ` Matthew Garrett
2012-07-10 16:35 ` Seth Forshee
2012-07-11 0:25 ` Andreas Heider
2012-07-29 0:42 ` David Woodhouse
2012-07-29 1:18 ` David Woodhouse
2012-07-29 7:46 ` Andreas Heider
2012-07-29 19:05 ` David Woodhouse
2012-07-29 19:34 ` Andreas Heider
2012-07-29 22:44 ` David Woodhouse
2012-07-30 14:05 ` Seth Forshee
2012-07-29 19:39 ` Matthew Garrett [this message]
2012-07-29 20:33 ` David Woodhouse
2012-07-29 20:52 ` David Woodhouse
2012-07-29 20:59 ` Matthew Garrett
2012-07-31 15:18 ` Seth Forshee
2012-07-31 17:07 ` Seth Forshee
2012-08-01 15:35 ` David Woodhouse
2012-08-01 15:59 ` Seth Forshee
2012-08-01 16:06 ` Andreas Heider
2012-08-01 19:41 ` David Woodhouse
2012-08-01 19:52 ` Seth Forshee
2012-08-01 19:43 ` David Woodhouse
2012-08-01 19:52 ` Matthew Garrett
2012-08-01 19:56 ` Seth Forshee
2012-08-01 19:56 ` Andreas Heider
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120729193953.GA25132@srcf.ucam.org \
--to=mjg59@srcf.ucam.org \
--cc=andreas@meetr.de \
--cc=arun.raghavan@collabora.co.uk \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.