diff options
-rw-r--r-- | drivers/gpu/drm/i915/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_opregion.c | 113 |
7 files changed, 141 insertions, 98 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 345ca52d6e84..f6e98dd416c9 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -26,13 +26,13 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
26 | intel_dvo.o \ | 26 | intel_dvo.o \ |
27 | intel_ringbuffer.o \ | 27 | intel_ringbuffer.o \ |
28 | intel_overlay.o \ | 28 | intel_overlay.o \ |
29 | intel_opregion.o \ | ||
29 | dvo_ch7xxx.o \ | 30 | dvo_ch7xxx.o \ |
30 | dvo_ch7017.o \ | 31 | dvo_ch7017.o \ |
31 | dvo_ivch.o \ | 32 | dvo_ivch.o \ |
32 | dvo_tfp410.o \ | 33 | dvo_tfp410.o \ |
33 | dvo_sil164.o | 34 | dvo_sil164.o |
34 | 35 | ||
35 | i915-$(CONFIG_ACPI) += intel_opregion.o | ||
36 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 36 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
37 | 37 | ||
38 | obj-$(CONFIG_DRM_I915) += i915.o | 38 | obj-$(CONFIG_DRM_I915) += i915.o |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5e43d7076789..16133f10ffaa 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -718,6 +718,26 @@ static int i915_gfxec(struct seq_file *m, void *unused) | |||
718 | return 0; | 718 | return 0; |
719 | } | 719 | } |
720 | 720 | ||
721 | static int i915_opregion(struct seq_file *m, void *unused) | ||
722 | { | ||
723 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
724 | struct drm_device *dev = node->minor->dev; | ||
725 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
726 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
727 | int ret; | ||
728 | |||
729 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
730 | if (ret) | ||
731 | return ret; | ||
732 | |||
733 | if (opregion->header) | ||
734 | seq_write(m, opregion->header, OPREGION_SIZE); | ||
735 | |||
736 | mutex_unlock(&dev->struct_mutex); | ||
737 | |||
738 | return 0; | ||
739 | } | ||
740 | |||
721 | static int | 741 | static int |
722 | i915_wedged_open(struct inode *inode, | 742 | i915_wedged_open(struct inode *inode, |
723 | struct file *filp) | 743 | struct file *filp) |
@@ -845,6 +865,7 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
845 | {"i915_gfxec", i915_gfxec, 0}, | 865 | {"i915_gfxec", i915_gfxec, 0}, |
846 | {"i915_fbc_status", i915_fbc_status, 0}, | 866 | {"i915_fbc_status", i915_fbc_status, 0}, |
847 | {"i915_sr_status", i915_sr_status, 0}, | 867 | {"i915_sr_status", i915_sr_status, 0}, |
868 | {"i915_opregion", i915_opregion, 0}, | ||
848 | }; | 869 | }; |
849 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) | 870 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
850 | 871 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c58ec5c02919..2dae3be9ebef 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/pnp.h> | 40 | #include <linux/pnp.h> |
41 | #include <linux/vga_switcheroo.h> | 41 | #include <linux/vga_switcheroo.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <acpi/video.h> | ||
43 | 44 | ||
44 | extern int intel_max_stolen; /* from AGP driver */ | 45 | extern int intel_max_stolen; /* from AGP driver */ |
45 | 46 | ||
@@ -2166,6 +2167,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2166 | 2167 | ||
2167 | /* Try to make sure MCHBAR is enabled before poking at it */ | 2168 | /* Try to make sure MCHBAR is enabled before poking at it */ |
2168 | intel_setup_mchbar(dev); | 2169 | intel_setup_mchbar(dev); |
2170 | intel_opregion_setup(dev); | ||
2169 | 2171 | ||
2170 | i915_gem_load(dev); | 2172 | i915_gem_load(dev); |
2171 | 2173 | ||
@@ -2221,7 +2223,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2221 | } | 2223 | } |
2222 | 2224 | ||
2223 | /* Must be done after probing outputs */ | 2225 | /* Must be done after probing outputs */ |
2224 | intel_opregion_init(dev, 0); | 2226 | intel_opregion_init(dev); |
2227 | acpi_video_register(); | ||
2225 | 2228 | ||
2226 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, | 2229 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
2227 | (unsigned long) dev); | 2230 | (unsigned long) dev); |
@@ -2271,6 +2274,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
2271 | dev_priv->mm.gtt_mtrr = -1; | 2274 | dev_priv->mm.gtt_mtrr = -1; |
2272 | } | 2275 | } |
2273 | 2276 | ||
2277 | acpi_video_unregister(); | ||
2278 | |||
2274 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2279 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2275 | intel_modeset_cleanup(dev); | 2280 | intel_modeset_cleanup(dev); |
2276 | 2281 | ||
@@ -2299,7 +2304,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2299 | if (dev_priv->regs != NULL) | 2304 | if (dev_priv->regs != NULL) |
2300 | iounmap(dev_priv->regs); | 2305 | iounmap(dev_priv->regs); |
2301 | 2306 | ||
2302 | intel_opregion_free(dev, 0); | 2307 | intel_opregion_fini(dev); |
2303 | 2308 | ||
2304 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2309 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2305 | /* Flush any outstanding unpin_work. */ | 2310 | /* Flush any outstanding unpin_work. */ |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ba75255ec450..2879a768d65c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -236,7 +236,7 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
236 | 236 | ||
237 | i915_save_state(dev); | 237 | i915_save_state(dev); |
238 | 238 | ||
239 | intel_opregion_free(dev, 1); | 239 | intel_opregion_fini(dev); |
240 | 240 | ||
241 | /* Modeset on resume, not lid events */ | 241 | /* Modeset on resume, not lid events */ |
242 | dev_priv->modeset_on_lid = 0; | 242 | dev_priv->modeset_on_lid = 0; |
@@ -276,8 +276,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
276 | int error = 0; | 276 | int error = 0; |
277 | 277 | ||
278 | i915_restore_state(dev); | 278 | i915_restore_state(dev); |
279 | 279 | intel_opregion_setup(dev); | |
280 | intel_opregion_init(dev, 1); | ||
281 | 280 | ||
282 | /* KMS EnterVT equivalent */ | 281 | /* KMS EnterVT equivalent */ |
283 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 282 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
@@ -293,6 +292,8 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
293 | drm_helper_resume_force_mode(dev); | 292 | drm_helper_resume_force_mode(dev); |
294 | } | 293 | } |
295 | 294 | ||
295 | intel_opregion_init(dev); | ||
296 | |||
296 | dev_priv->modeset_on_lid = 0; | 297 | dev_priv->modeset_on_lid = 0; |
297 | 298 | ||
298 | return error; | 299 | return error; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 980061ff5c80..f6940f1b1286 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -110,8 +110,9 @@ struct intel_opregion { | |||
110 | struct opregion_acpi *acpi; | 110 | struct opregion_acpi *acpi; |
111 | struct opregion_swsci *swsci; | 111 | struct opregion_swsci *swsci; |
112 | struct opregion_asle *asle; | 112 | struct opregion_asle *asle; |
113 | int enabled; | 113 | void *vbt; |
114 | }; | 114 | }; |
115 | #define OPREGION_SIZE (8*1024) | ||
115 | 116 | ||
116 | struct intel_overlay; | 117 | struct intel_overlay; |
117 | struct intel_overlay_error_state; | 118 | struct intel_overlay_error_state; |
@@ -1053,16 +1054,17 @@ extern int i915_restore_state(struct drm_device *dev); | |||
1053 | extern int i915_save_state(struct drm_device *dev); | 1054 | extern int i915_save_state(struct drm_device *dev); |
1054 | extern int i915_restore_state(struct drm_device *dev); | 1055 | extern int i915_restore_state(struct drm_device *dev); |
1055 | 1056 | ||
1056 | #ifdef CONFIG_ACPI | ||
1057 | /* intel_opregion.c */ | 1057 | /* intel_opregion.c */ |
1058 | extern int intel_opregion_init(struct drm_device *dev, int resume); | 1058 | extern int intel_opregion_setup(struct drm_device *dev); |
1059 | extern void intel_opregion_free(struct drm_device *dev, int suspend); | 1059 | #ifdef CONFIG_ACPI |
1060 | extern void intel_opregion_init(struct drm_device *dev); | ||
1061 | extern void intel_opregion_fini(struct drm_device *dev); | ||
1060 | extern void intel_opregion_asle_intr(struct drm_device *dev); | 1062 | extern void intel_opregion_asle_intr(struct drm_device *dev); |
1061 | extern void intel_opregion_gse_intr(struct drm_device *dev); | 1063 | extern void intel_opregion_gse_intr(struct drm_device *dev); |
1062 | extern void intel_opregion_enable_asle(struct drm_device *dev); | 1064 | extern void intel_opregion_enable_asle(struct drm_device *dev); |
1063 | #else | 1065 | #else |
1064 | static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } | 1066 | static inline void intel_opregion_init(struct drm_device *dev) { return; } |
1065 | static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; } | 1067 | static inline void intel_opregion_fini(struct drm_device *dev) { return; } |
1066 | static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } | 1068 | static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } |
1067 | static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } | 1069 | static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } |
1068 | static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } | 1070 | static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 96f75d7f6633..8d7deca69830 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -317,7 +317,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv, | |||
317 | 317 | ||
318 | static void | 318 | static void |
319 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | 319 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, |
320 | struct bdb_header *bdb) | 320 | struct bdb_header *bdb) |
321 | { | 321 | { |
322 | struct sdvo_device_mapping *p_mapping; | 322 | struct sdvo_device_mapping *p_mapping; |
323 | struct bdb_general_definitions *p_defs; | 323 | struct bdb_general_definitions *p_defs; |
@@ -327,7 +327,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
327 | 327 | ||
328 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 328 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
329 | if (!p_defs) { | 329 | if (!p_defs) { |
330 | DRM_DEBUG_KMS("No general definition block is found\n"); | 330 | DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); |
331 | return; | 331 | return; |
332 | } | 332 | } |
333 | /* judge whether the size of child device meets the requirements. | 333 | /* judge whether the size of child device meets the requirements. |
@@ -460,7 +460,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
460 | 460 | ||
461 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 461 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
462 | if (!p_defs) { | 462 | if (!p_defs) { |
463 | DRM_DEBUG_KMS("No general definition block is found\n"); | 463 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
464 | return; | 464 | return; |
465 | } | 465 | } |
466 | /* judge whether the size of child device meets the requirements. | 466 | /* judge whether the size of child device meets the requirements. |
@@ -513,6 +513,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
513 | } | 513 | } |
514 | return; | 514 | return; |
515 | } | 515 | } |
516 | |||
516 | /** | 517 | /** |
517 | * intel_init_bios - initialize VBIOS settings & find VBT | 518 | * intel_init_bios - initialize VBIOS settings & find VBT |
518 | * @dev: DRM device | 519 | * @dev: DRM device |
@@ -520,11 +521,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
520 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers | 521 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers |
521 | * to appropriate values. | 522 | * to appropriate values. |
522 | * | 523 | * |
523 | * VBT existence is a sanity check that is relied on by other i830_bios.c code. | ||
524 | * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may | ||
525 | * feed an updated VBT back through that, compared to what we'll fetch using | ||
526 | * this method of groping around in the BIOS data. | ||
527 | * | ||
528 | * Returns 0 on success, nonzero on failure. | 524 | * Returns 0 on success, nonzero on failure. |
529 | */ | 525 | */ |
530 | bool | 526 | bool |
@@ -532,31 +528,45 @@ intel_init_bios(struct drm_device *dev) | |||
532 | { | 528 | { |
533 | struct drm_i915_private *dev_priv = dev->dev_private; | 529 | struct drm_i915_private *dev_priv = dev->dev_private; |
534 | struct pci_dev *pdev = dev->pdev; | 530 | struct pci_dev *pdev = dev->pdev; |
535 | struct vbt_header *vbt = NULL; | 531 | struct bdb_header *bdb = NULL; |
536 | struct bdb_header *bdb; | 532 | u8 __iomem *bios = NULL; |
537 | u8 __iomem *bios; | 533 | |
538 | size_t size; | 534 | /* XXX Should this validation be moved to intel_opregion.c? */ |
539 | int i; | 535 | if (dev_priv->opregion.vbt) { |
540 | 536 | struct vbt_header *vbt = dev_priv->opregion.vbt; | |
541 | bios = pci_map_rom(pdev, &size); | 537 | if (memcmp(vbt->signature, "$VBT", 4) == 0) { |
542 | if (!bios) | 538 | DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n", |
543 | return -1; | 539 | vbt->signature); |
544 | 540 | bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); | |
545 | /* Scour memory looking for the VBT signature */ | 541 | } else |
546 | for (i = 0; i + 4 < size; i++) { | 542 | dev_priv->opregion.vbt = NULL; |
547 | if (!memcmp(bios + i, "$VBT", 4)) { | ||
548 | vbt = (struct vbt_header *)(bios + i); | ||
549 | break; | ||
550 | } | ||
551 | } | 543 | } |
552 | 544 | ||
553 | if (!vbt) { | 545 | if (bdb == NULL) { |
554 | DRM_ERROR("VBT signature missing\n"); | 546 | struct vbt_header *vbt = NULL; |
555 | pci_unmap_rom(pdev, bios); | 547 | size_t size; |
556 | return -1; | 548 | int i; |
557 | } | ||
558 | 549 | ||
559 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | 550 | bios = pci_map_rom(pdev, &size); |
551 | if (!bios) | ||
552 | return -1; | ||
553 | |||
554 | /* Scour memory looking for the VBT signature */ | ||
555 | for (i = 0; i + 4 < size; i++) { | ||
556 | if (!memcmp(bios + i, "$VBT", 4)) { | ||
557 | vbt = (struct vbt_header *)(bios + i); | ||
558 | break; | ||
559 | } | ||
560 | } | ||
561 | |||
562 | if (!vbt) { | ||
563 | DRM_ERROR("VBT signature missing\n"); | ||
564 | pci_unmap_rom(pdev, bios); | ||
565 | return -1; | ||
566 | } | ||
567 | |||
568 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | ||
569 | } | ||
560 | 570 | ||
561 | /* Grab useful general definitions */ | 571 | /* Grab useful general definitions */ |
562 | parse_general_features(dev_priv, bdb); | 572 | parse_general_features(dev_priv, bdb); |
@@ -568,7 +578,8 @@ intel_init_bios(struct drm_device *dev) | |||
568 | parse_driver_features(dev_priv, bdb); | 578 | parse_driver_features(dev_priv, bdb); |
569 | parse_edp(dev_priv, bdb); | 579 | parse_edp(dev_priv, bdb); |
570 | 580 | ||
571 | pci_unmap_rom(pdev, bios); | 581 | if (bios) |
582 | pci_unmap_rom(pdev, bios); | ||
572 | 583 | ||
573 | return 0; | 584 | return 0; |
574 | } | 585 | } |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 97d5329079fe..3cb13237ba58 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -36,12 +36,11 @@ | |||
36 | #define PCI_LBPC 0xf4 | 36 | #define PCI_LBPC 0xf4 |
37 | #define PCI_ASLS 0xfc | 37 | #define PCI_ASLS 0xfc |
38 | 38 | ||
39 | #define OPREGION_SZ (8*1024) | ||
40 | #define OPREGION_HEADER_OFFSET 0 | 39 | #define OPREGION_HEADER_OFFSET 0 |
41 | #define OPREGION_ACPI_OFFSET 0x100 | 40 | #define OPREGION_ACPI_OFFSET 0x100 |
42 | #define OPREGION_SWSCI_OFFSET 0x200 | 41 | #define OPREGION_SWSCI_OFFSET 0x200 |
43 | #define OPREGION_ASLE_OFFSET 0x300 | 42 | #define OPREGION_ASLE_OFFSET 0x300 |
44 | #define OPREGION_VBT_OFFSET 0x1000 | 43 | #define OPREGION_VBT_OFFSET 0x400 |
45 | 44 | ||
46 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | 45 | #define OPREGION_SIGNATURE "IntelGraphicsMem" |
47 | #define MBOX_ACPI (1<<0) | 46 | #define MBOX_ACPI (1<<0) |
@@ -143,6 +142,7 @@ struct opregion_asle { | |||
143 | #define ACPI_DIGITAL_OUTPUT (3<<8) | 142 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
144 | #define ACPI_LVDS_OUTPUT (4<<8) | 143 | #define ACPI_LVDS_OUTPUT (4<<8) |
145 | 144 | ||
145 | #ifdef CONFIG_ACPI | ||
146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
147 | { | 147 | { |
148 | struct drm_i915_private *dev_priv = dev->dev_private; | 148 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -465,7 +465,58 @@ blind_set: | |||
465 | goto end; | 465 | goto end; |
466 | } | 466 | } |
467 | 467 | ||
468 | int intel_opregion_init(struct drm_device *dev, int resume) | 468 | void intel_opregion_init(struct drm_device *dev) |
469 | { | ||
470 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
471 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
472 | |||
473 | if (!opregion->header) | ||
474 | return; | ||
475 | |||
476 | if (opregion->acpi) { | ||
477 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
478 | intel_didl_outputs(dev); | ||
479 | |||
480 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
481 | * Right now, all the events are handled by the ACPI video module. | ||
482 | * We don't actually need to do anything with them. */ | ||
483 | opregion->acpi->csts = 0; | ||
484 | opregion->acpi->drdy = 1; | ||
485 | |||
486 | system_opregion = opregion; | ||
487 | register_acpi_notifier(&intel_opregion_notifier); | ||
488 | } | ||
489 | |||
490 | if (opregion->asle) | ||
491 | intel_opregion_enable_asle(dev); | ||
492 | } | ||
493 | |||
494 | void intel_opregion_fini(struct drm_device *dev) | ||
495 | { | ||
496 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
497 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
498 | |||
499 | if (!opregion->header) | ||
500 | return; | ||
501 | |||
502 | if (opregion->acpi) { | ||
503 | opregion->acpi->drdy = 0; | ||
504 | |||
505 | system_opregion = NULL; | ||
506 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
507 | } | ||
508 | |||
509 | /* just clear all opregion memory pointers now */ | ||
510 | iounmap(opregion->header); | ||
511 | opregion->header = NULL; | ||
512 | opregion->acpi = NULL; | ||
513 | opregion->swsci = NULL; | ||
514 | opregion->asle = NULL; | ||
515 | opregion->vbt = NULL; | ||
516 | } | ||
517 | #endif | ||
518 | |||
519 | int intel_opregion_setup(struct drm_device *dev) | ||
469 | { | 520 | { |
470 | struct drm_i915_private *dev_priv = dev->dev_private; | 521 | struct drm_i915_private *dev_priv = dev->dev_private; |
471 | struct intel_opregion *opregion = &dev_priv->opregion; | 522 | struct intel_opregion *opregion = &dev_priv->opregion; |
@@ -480,29 +531,23 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
480 | return -ENOTSUPP; | 531 | return -ENOTSUPP; |
481 | } | 532 | } |
482 | 533 | ||
483 | base = ioremap(asls, OPREGION_SZ); | 534 | base = ioremap(asls, OPREGION_SIZE); |
484 | if (!base) | 535 | if (!base) |
485 | return -ENOMEM; | 536 | return -ENOMEM; |
486 | 537 | ||
487 | opregion->header = base; | 538 | if (memcmp(base, OPREGION_SIGNATURE, 16)) { |
488 | if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { | ||
489 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); | 539 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); |
490 | err = -EINVAL; | 540 | err = -EINVAL; |
491 | goto err_out; | 541 | goto err_out; |
492 | } | 542 | } |
543 | opregion->header = base; | ||
544 | opregion->vbt = base + OPREGION_VBT_OFFSET; | ||
493 | 545 | ||
494 | mboxes = opregion->header->mboxes; | 546 | mboxes = opregion->header->mboxes; |
495 | if (mboxes & MBOX_ACPI) { | 547 | if (mboxes & MBOX_ACPI) { |
496 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); | 548 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); |
497 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | 549 | opregion->acpi = base + OPREGION_ACPI_OFFSET; |
498 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
499 | intel_didl_outputs(dev); | ||
500 | } else { | ||
501 | DRM_DEBUG_DRIVER("Public ACPI methods not supported\n"); | ||
502 | err = -ENOTSUPP; | ||
503 | goto err_out; | ||
504 | } | 550 | } |
505 | opregion->enabled = 1; | ||
506 | 551 | ||
507 | if (mboxes & MBOX_SWSCI) { | 552 | if (mboxes & MBOX_SWSCI) { |
508 | DRM_DEBUG_DRIVER("SWSCI supported\n"); | 553 | DRM_DEBUG_DRIVER("SWSCI supported\n"); |
@@ -511,53 +556,11 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
511 | if (mboxes & MBOX_ASLE) { | 556 | if (mboxes & MBOX_ASLE) { |
512 | DRM_DEBUG_DRIVER("ASLE supported\n"); | 557 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
513 | opregion->asle = base + OPREGION_ASLE_OFFSET; | 558 | opregion->asle = base + OPREGION_ASLE_OFFSET; |
514 | intel_opregion_enable_asle(dev); | ||
515 | } | 559 | } |
516 | 560 | ||
517 | if (!resume) | ||
518 | acpi_video_register(); | ||
519 | |||
520 | |||
521 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
522 | * Right now, all the events are handled by the ACPI video module. | ||
523 | * We don't actually need to do anything with them. */ | ||
524 | opregion->acpi->csts = 0; | ||
525 | opregion->acpi->drdy = 1; | ||
526 | |||
527 | system_opregion = opregion; | ||
528 | register_acpi_notifier(&intel_opregion_notifier); | ||
529 | |||
530 | return 0; | 561 | return 0; |
531 | 562 | ||
532 | err_out: | 563 | err_out: |
533 | iounmap(opregion->header); | 564 | iounmap(opregion->header); |
534 | opregion->header = NULL; | ||
535 | acpi_video_register(); | ||
536 | return err; | 565 | return err; |
537 | } | 566 | } |
538 | |||
539 | void intel_opregion_free(struct drm_device *dev, int suspend) | ||
540 | { | ||
541 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
542 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
543 | |||
544 | if (!opregion->enabled) | ||
545 | return; | ||
546 | |||
547 | if (!suspend) | ||
548 | acpi_video_unregister(); | ||
549 | |||
550 | opregion->acpi->drdy = 0; | ||
551 | |||
552 | system_opregion = NULL; | ||
553 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
554 | |||
555 | /* just clear all opregion memory pointers now */ | ||
556 | iounmap(opregion->header); | ||
557 | opregion->header = NULL; | ||
558 | opregion->acpi = NULL; | ||
559 | opregion->swsci = NULL; | ||
560 | opregion->asle = NULL; | ||
561 | |||
562 | opregion->enabled = 0; | ||
563 | } | ||