diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_opregion.c | 65 |
4 files changed, 70 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6d21b9e48b89..638686904e06 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1144,8 +1144,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1144 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 1144 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
1145 | pci_enable_msi(dev->pdev); | 1145 | pci_enable_msi(dev->pdev); |
1146 | 1146 | ||
1147 | intel_opregion_init(dev); | ||
1148 | |||
1149 | spin_lock_init(&dev_priv->user_irq_lock); | 1147 | spin_lock_init(&dev_priv->user_irq_lock); |
1150 | dev_priv->user_irq_refcount = 0; | 1148 | dev_priv->user_irq_refcount = 0; |
1151 | 1149 | ||
@@ -1164,6 +1162,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1164 | } | 1162 | } |
1165 | } | 1163 | } |
1166 | 1164 | ||
1165 | /* Must be done after probing outputs */ | ||
1166 | intel_opregion_init(dev, 0); | ||
1167 | |||
1167 | return 0; | 1168 | return 0; |
1168 | 1169 | ||
1169 | out_iomapfree: | 1170 | out_iomapfree: |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b293ef0bae71..209592fdb7e7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -99,7 +99,7 @@ static int i915_resume(struct drm_device *dev) | |||
99 | 99 | ||
100 | i915_restore_state(dev); | 100 | i915_restore_state(dev); |
101 | 101 | ||
102 | intel_opregion_init(dev); | 102 | intel_opregion_init(dev, 1); |
103 | 103 | ||
104 | /* KMS EnterVT equivalent */ | 104 | /* KMS EnterVT equivalent */ |
105 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 105 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d6cc9861e0a1..b9a92c250b91 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -659,12 +659,12 @@ extern int i915_restore_state(struct drm_device *dev); | |||
659 | 659 | ||
660 | #ifdef CONFIG_ACPI | 660 | #ifdef CONFIG_ACPI |
661 | /* i915_opregion.c */ | 661 | /* i915_opregion.c */ |
662 | extern int intel_opregion_init(struct drm_device *dev); | 662 | extern int intel_opregion_init(struct drm_device *dev, int resume); |
663 | extern void intel_opregion_free(struct drm_device *dev); | 663 | extern void intel_opregion_free(struct drm_device *dev); |
664 | extern void opregion_asle_intr(struct drm_device *dev); | 664 | extern void opregion_asle_intr(struct drm_device *dev); |
665 | extern void opregion_enable_asle(struct drm_device *dev); | 665 | extern void opregion_enable_asle(struct drm_device *dev); |
666 | #else | 666 | #else |
667 | static inline int intel_opregion_init(struct drm_device *dev) { return 0; } | 667 | static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } |
668 | static inline void intel_opregion_free(struct drm_device *dev) { return; } | 668 | static inline void intel_opregion_free(struct drm_device *dev) { return; } |
669 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } | 669 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } |
670 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } | 670 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } |
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index ff012835a386..69427722d20e 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <acpi/video.h> | ||
29 | 30 | ||
30 | #include "drmP.h" | 31 | #include "drmP.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -136,6 +137,12 @@ struct opregion_asle { | |||
136 | 137 | ||
137 | #define ASLE_CBLV_VALID (1<<31) | 138 | #define ASLE_CBLV_VALID (1<<31) |
138 | 139 | ||
140 | #define ACPI_OTHER_OUTPUT (0<<8) | ||
141 | #define ACPI_VGA_OUTPUT (1<<8) | ||
142 | #define ACPI_TV_OUTPUT (2<<8) | ||
143 | #define ACPI_DIGITAL_OUTPUT (3<<8) | ||
144 | #define ACPI_LVDS_OUTPUT (4<<8) | ||
145 | |||
139 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
140 | { | 147 | { |
141 | struct drm_i915_private *dev_priv = dev->dev_private; | 148 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -282,7 +289,58 @@ static struct notifier_block intel_opregion_notifier = { | |||
282 | .notifier_call = intel_opregion_video_event, | 289 | .notifier_call = intel_opregion_video_event, |
283 | }; | 290 | }; |
284 | 291 | ||
285 | int intel_opregion_init(struct drm_device *dev) | 292 | /* |
293 | * Initialise the DIDL field in opregion. This passes a list of devices to | ||
294 | * the firmware. Values are defined by section B.4.2 of the ACPI specification | ||
295 | * (version 3) | ||
296 | */ | ||
297 | |||
298 | static void intel_didl_outputs(struct drm_device *dev) | ||
299 | { | ||
300 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
301 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
302 | struct drm_connector *connector; | ||
303 | int i = 0; | ||
304 | |||
305 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
306 | int output_type = ACPI_OTHER_OUTPUT; | ||
307 | if (i >= 8) { | ||
308 | dev_printk (KERN_ERR, &dev->pdev->dev, | ||
309 | "More than 8 outputs detected\n"); | ||
310 | return; | ||
311 | } | ||
312 | switch (connector->connector_type) { | ||
313 | case DRM_MODE_CONNECTOR_VGA: | ||
314 | case DRM_MODE_CONNECTOR_DVIA: | ||
315 | output_type = ACPI_VGA_OUTPUT; | ||
316 | break; | ||
317 | case DRM_MODE_CONNECTOR_Composite: | ||
318 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
319 | case DRM_MODE_CONNECTOR_Component: | ||
320 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
321 | output_type = ACPI_TV_OUTPUT; | ||
322 | break; | ||
323 | case DRM_MODE_CONNECTOR_DVII: | ||
324 | case DRM_MODE_CONNECTOR_DVID: | ||
325 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
326 | case DRM_MODE_CONNECTOR_HDMIA: | ||
327 | case DRM_MODE_CONNECTOR_HDMIB: | ||
328 | output_type = ACPI_DIGITAL_OUTPUT; | ||
329 | break; | ||
330 | case DRM_MODE_CONNECTOR_LVDS: | ||
331 | output_type = ACPI_LVDS_OUTPUT; | ||
332 | break; | ||
333 | } | ||
334 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; | ||
335 | i++; | ||
336 | } | ||
337 | |||
338 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
339 | if (i < 8) | ||
340 | opregion->acpi->didl[i] = 0; | ||
341 | } | ||
342 | |||
343 | int intel_opregion_init(struct drm_device *dev, int resume) | ||
286 | { | 344 | { |
287 | struct drm_i915_private *dev_priv = dev->dev_private; | 345 | struct drm_i915_private *dev_priv = dev->dev_private; |
288 | struct intel_opregion *opregion = &dev_priv->opregion; | 346 | struct intel_opregion *opregion = &dev_priv->opregion; |
@@ -312,6 +370,11 @@ int intel_opregion_init(struct drm_device *dev) | |||
312 | if (mboxes & MBOX_ACPI) { | 370 | if (mboxes & MBOX_ACPI) { |
313 | DRM_DEBUG("Public ACPI methods supported\n"); | 371 | DRM_DEBUG("Public ACPI methods supported\n"); |
314 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | 372 | opregion->acpi = base + OPREGION_ACPI_OFFSET; |
373 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
374 | intel_didl_outputs(dev); | ||
375 | if (!resume) | ||
376 | acpi_video_register(); | ||
377 | } | ||
315 | } else { | 378 | } else { |
316 | DRM_DEBUG("Public ACPI methods not supported\n"); | 379 | DRM_DEBUG("Public ACPI methods not supported\n"); |
317 | err = -ENOTSUPP; | 380 | err = -ENOTSUPP; |