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 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome