diff options
author | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-04-07 10:35:50 -0400 |
---|---|---|
committer | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2013-04-07 11:09:37 -0400 |
commit | 749387dc8d8270b279f27a0a794cdf4f4a4aa774 (patch) | |
tree | af60d046754eed815c74952f2fa8129580aa6d04 | |
parent | 888eef2e8c2d9fc2e6ccf58fb4a8f9f6d8ff9a22 (diff) |
drm/gma500: Fix hibernation problems on sdvo encoders
The state of the SDVO chip is more difficult to save than the LVDS so we do a
full mode set on the crtc to get SDVO operational again. The SDVOB/C register is
also stored just in case we have special bits set in the future.
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_sdvo.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index a4cc777ab7a6..cd1b40722edd 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -134,6 +134,9 @@ struct psb_intel_sdvo { | |||
134 | 134 | ||
135 | /* Input timings for adjusted_mode */ | 135 | /* Input timings for adjusted_mode */ |
136 | struct psb_intel_sdvo_dtd input_dtd; | 136 | struct psb_intel_sdvo_dtd input_dtd; |
137 | |||
138 | /* Saved SDVO output states */ | ||
139 | uint32_t saveSDVO; /* Can be SDVOB or SDVOC depending on sdvo_reg */ | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | struct psb_intel_sdvo_connector { | 142 | struct psb_intel_sdvo_connector { |
@@ -1830,6 +1833,35 @@ done: | |||
1830 | #undef CHECK_PROPERTY | 1833 | #undef CHECK_PROPERTY |
1831 | } | 1834 | } |
1832 | 1835 | ||
1836 | static void psb_intel_sdvo_save(struct drm_connector *connector) | ||
1837 | { | ||
1838 | struct drm_device *dev = connector->dev; | ||
1839 | struct psb_intel_encoder *psb_intel_encoder = | ||
1840 | psb_intel_attached_encoder(connector); | ||
1841 | struct psb_intel_sdvo *sdvo = | ||
1842 | to_psb_intel_sdvo(&psb_intel_encoder->base); | ||
1843 | |||
1844 | sdvo->saveSDVO = REG_READ(sdvo->sdvo_reg); | ||
1845 | } | ||
1846 | |||
1847 | static void psb_intel_sdvo_restore(struct drm_connector *connector) | ||
1848 | { | ||
1849 | struct drm_device *dev = connector->dev; | ||
1850 | struct drm_encoder *encoder = | ||
1851 | &psb_intel_attached_encoder(connector)->base; | ||
1852 | struct psb_intel_sdvo *sdvo = to_psb_intel_sdvo(encoder); | ||
1853 | struct drm_crtc *crtc = encoder->crtc; | ||
1854 | |||
1855 | REG_WRITE(sdvo->sdvo_reg, sdvo->saveSDVO); | ||
1856 | |||
1857 | /* Force dpms on upon resume */ | ||
1858 | psb_intel_sdvo_dpms(encoder, DRM_MODE_DPMS_ON); | ||
1859 | |||
1860 | /* Force a full mode set on the crtc. We're supposed to have the | ||
1861 | mode_config lock already. */ | ||
1862 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, NULL); | ||
1863 | } | ||
1864 | |||
1833 | static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { | 1865 | static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { |
1834 | .dpms = psb_intel_sdvo_dpms, | 1866 | .dpms = psb_intel_sdvo_dpms, |
1835 | .mode_fixup = psb_intel_sdvo_mode_fixup, | 1867 | .mode_fixup = psb_intel_sdvo_mode_fixup, |
@@ -1840,6 +1872,8 @@ static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { | |||
1840 | 1872 | ||
1841 | static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { | 1873 | static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { |
1842 | .dpms = drm_helper_connector_dpms, | 1874 | .dpms = drm_helper_connector_dpms, |
1875 | .save = psb_intel_sdvo_save, | ||
1876 | .restore = psb_intel_sdvo_restore, | ||
1843 | .detect = psb_intel_sdvo_detect, | 1877 | .detect = psb_intel_sdvo_detect, |
1844 | .fill_modes = drm_helper_probe_single_connector_modes, | 1878 | .fill_modes = drm_helper_probe_single_connector_modes, |
1845 | .set_property = psb_intel_sdvo_set_property, | 1879 | .set_property = psb_intel_sdvo_set_property, |