aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c65
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
1169out_iomapfree: 1170out_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 */
662extern int intel_opregion_init(struct drm_device *dev); 662extern int intel_opregion_init(struct drm_device *dev, int resume);
663extern void intel_opregion_free(struct drm_device *dev); 663extern void intel_opregion_free(struct drm_device *dev);
664extern void opregion_asle_intr(struct drm_device *dev); 664extern void opregion_asle_intr(struct drm_device *dev);
665extern void opregion_enable_asle(struct drm_device *dev); 665extern void opregion_enable_asle(struct drm_device *dev);
666#else 666#else
667static inline int intel_opregion_init(struct drm_device *dev) { return 0; } 667static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
668static inline void intel_opregion_free(struct drm_device *dev) { return; } 668static inline void intel_opregion_free(struct drm_device *dev) { return; }
669static inline void opregion_asle_intr(struct drm_device *dev) { return; } 669static inline void opregion_asle_intr(struct drm_device *dev) { return; }
670static inline void opregion_enable_asle(struct drm_device *dev) { return; } 670static 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
139static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) 146static 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
285int 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
298static 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
343int 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;